mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 08:58:26 +00:00
@@ -3,9 +3,9 @@ title: Server Session
|
||||
category: Behavioral
|
||||
language: en
|
||||
tag:
|
||||
- Session Management
|
||||
- Session Tracking
|
||||
- Cookies
|
||||
- Session management
|
||||
- State tracking
|
||||
---
|
||||
|
||||
## Also known as
|
||||
@@ -20,7 +20,7 @@ Within the context of a client-server relationship, the server is responsible fo
|
||||
|
||||
Real-world example
|
||||
|
||||
> Consider a gaming website which stores user profile data such as username, password, highscore, hours played, etc. Since this website is accessed over the internet which uses the HTTP protocol, all requests sent to the server are stateless. In order for the page to display user relevent information without re-authenticating the user on every request a session must be created. Once the session is created the user can access the homescreen, statistics page, setting page, etc. and view profile specific data without needing to login in on every page request.
|
||||
> Consider a gaming website which stores user profile data such as username, password, high-score, hours played, etc. Since this website is accessed over the internet which uses the HTTP protocol, all requests sent to the server are stateless. In order for the page to display user relevant information without re-authenticating the user on every request a session must be created. Once the session is created the user can access the homescreen, statistics page, setting page, etc. and view profile specific data without needing to log in on every page request.
|
||||
|
||||
In plain words
|
||||
|
||||
@@ -179,13 +179,13 @@ Sessions are often given a maximum time in which they will be maintained. The se
|
||||
|
||||
## Class diagram
|
||||
|
||||

|
||||

|
||||
|
||||
## Applicability
|
||||
|
||||
Use the Adapter pattern when
|
||||
|
||||
* When a user logs into a website or web application and you want to keep track of their authentication status.
|
||||
* When a user logs into a website or web application, and you want to keep track of their authentication status.
|
||||
* In e-commerce websites when you want to maintain the contents of a user's shopping cart across different pages and visits.
|
||||
* When you want to store user preferences and settings, such as language preferences, theme choices, or any other customizable options.
|
||||
* When you want to keep track of user activity and behavior on a website for the sake of analytics purposes.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
@startuml
|
||||
package com.iluwatar.sessionserver {
|
||||
class App {
|
||||
- LOGGER : Logger {static}
|
||||
- SESSION_EXPIRATION_TIME : long {static}
|
||||
- sessionCreationTimes : Map<String, Instant> {static}
|
||||
- sessions : Map<String, Integer> {static}
|
||||
+ App()
|
||||
+ main(args : String[]) {static}
|
||||
- sessionExpirationTask() {static}
|
||||
}
|
||||
class LoginHandler {
|
||||
- LOGGER : Logger {static}
|
||||
- sessionCreationTimes : Map<String, Instant>
|
||||
- sessions : Map<String, Integer>
|
||||
+ LoginHandler(sessions : Map<String, Integer>, sessionCreationTimes : Map<String, Instant>)
|
||||
+ handle(exchange : HttpExchange)
|
||||
}
|
||||
class LogoutHandler {
|
||||
- LOGGER : Logger {static}
|
||||
- sessionCreationTimes : Map<String, Instant>
|
||||
- sessions : Map<String, Integer>
|
||||
+ LogoutHandler(sessions : Map<String, Integer>, sessionCreationTimes : Map<String, Instant>)
|
||||
+ handle(exchange : HttpExchange)
|
||||
}
|
||||
}
|
||||
@enduml
|
||||
@@ -9,19 +9,17 @@
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.26.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>serversession</artifactId>
|
||||
<artifactId>server-session</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.10.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>5.11.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.iluwatar.sessionserver;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
@@ -32,48 +34,54 @@ public class App {
|
||||
private static Map<String, Instant> sessionCreationTimes = new HashMap<>();
|
||||
private static final long SESSION_EXPIRATION_TIME = 10000;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// Create HTTP server listening on port 8000
|
||||
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
|
||||
/**
|
||||
* Main entry point.
|
||||
* @param args arguments
|
||||
* @throws IOException ex
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
// Create HTTP server listening on port 8000
|
||||
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
|
||||
|
||||
// Set up session management endpoints
|
||||
server.createContext("/login", new LoginHandler(sessions, sessionCreationTimes));
|
||||
server.createContext("/logout", new LogoutHandler(sessions, sessionCreationTimes));
|
||||
// Set up session management endpoints
|
||||
server.createContext("/login", new LoginHandler(sessions, sessionCreationTimes));
|
||||
server.createContext("/logout", new LogoutHandler(sessions, sessionCreationTimes));
|
||||
|
||||
// Start the server
|
||||
server.start();
|
||||
// Start the server
|
||||
server.start();
|
||||
|
||||
// Start background task to check for expired sessions
|
||||
sessionExpirationTask();
|
||||
// Start background task to check for expired sessions
|
||||
sessionExpirationTask();
|
||||
|
||||
LOGGER.info("Server started. Listening on port 8080...");
|
||||
}
|
||||
LOGGER.info("Server started. Listening on port 8080...");
|
||||
}
|
||||
|
||||
private static void sessionExpirationTask() {
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
LOGGER.info("Session expiration checker started...");
|
||||
Thread.sleep(SESSION_EXPIRATION_TIME); // Sleep for expiration time
|
||||
Instant currentTime = Instant.now();
|
||||
synchronized (sessions) {
|
||||
synchronized (sessionCreationTimes) {
|
||||
Iterator<Map.Entry<String, Instant>> iterator = sessionCreationTimes.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, Instant> entry = iterator.next();
|
||||
if (entry.getValue().plusMillis(SESSION_EXPIRATION_TIME).isBefore(currentTime)) {
|
||||
sessions.remove(entry.getKey());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LOGGER.info("Session expiration checker finished!");
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
Thread.currentThread().interrupt();
|
||||
private static void sessionExpirationTask() {
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
LOGGER.info("Session expiration checker started...");
|
||||
Thread.sleep(SESSION_EXPIRATION_TIME); // Sleep for expiration time
|
||||
Instant currentTime = Instant.now();
|
||||
synchronized (sessions) {
|
||||
synchronized (sessionCreationTimes) {
|
||||
Iterator<Map.Entry<String, Instant>> iterator =
|
||||
sessionCreationTimes.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, Instant> entry = iterator.next();
|
||||
if (entry.getValue().plusMillis(SESSION_EXPIRATION_TIME).isBefore(currentTime)) {
|
||||
sessions.remove(entry.getKey());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
LOGGER.info("Session expiration checker finished!");
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -2,53 +2,52 @@ package com.iluwatar.sessionserver;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* LoginHandler.
|
||||
*/
|
||||
@Slf4j
|
||||
public class LoginHandler implements HttpHandler {
|
||||
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
|
||||
public LoginHandler(Map<String, Integer> sessions, Map<String, Instant> sessionCreationTimes) {
|
||||
this.sessions = sessions;
|
||||
this.sessionCreationTimes = sessionCreationTimes;
|
||||
public LoginHandler(Map<String, Integer> sessions, Map<String, Instant> sessionCreationTimes) {
|
||||
this.sessions = sessions;
|
||||
this.sessionCreationTimes = sessionCreationTimes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) {
|
||||
// Generate session ID
|
||||
String sessionId = UUID.randomUUID().toString();
|
||||
|
||||
// Store session data (simulated)
|
||||
int newUser = sessions.size() + 1;
|
||||
sessions.put(sessionId, newUser);
|
||||
sessionCreationTimes.put(sessionId, Instant.now());
|
||||
LOGGER.info("User " + newUser + " created at time " + sessionCreationTimes.get(sessionId));
|
||||
|
||||
// Set session ID as cookie
|
||||
exchange.getResponseHeaders().add("Set-Cookie", "sessionID=" + sessionId);
|
||||
|
||||
// Send response
|
||||
String response = "Login successful!\n" + "Session ID: " + sessionId;
|
||||
try {
|
||||
exchange.sendResponseHeaders(200, response.length());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) {
|
||||
// Generate session ID
|
||||
String sessionID = UUID.randomUUID().toString();
|
||||
|
||||
// Store session data (simulated)
|
||||
int newUser = sessions.size() + 1;
|
||||
sessions.put(sessionID, newUser);
|
||||
sessionCreationTimes.put(sessionID, Instant.now());
|
||||
LOGGER.info("User " + newUser + " created at time " + sessionCreationTimes.get(sessionID));
|
||||
|
||||
// Set session ID as cookie
|
||||
exchange.getResponseHeaders().add("Set-Cookie", "sessionID=" + sessionID);
|
||||
|
||||
// Send response
|
||||
String response = "Login successful!\n" +
|
||||
"Session ID: " + sessionID;
|
||||
try {
|
||||
exchange.sendResponseHeaders(200, response.length());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
}
|
||||
try(OutputStream os = exchange.getResponseBody()) {
|
||||
os.write(response.getBytes());
|
||||
} catch(IOException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
}
|
||||
try (OutputStream os = exchange.getResponseBody()) {
|
||||
os.write(response.getBytes());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("An error occurred: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,58 +2,60 @@ package com.iluwatar.sessionserver;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* LogoutHandler.
|
||||
*/
|
||||
@Slf4j
|
||||
public class LogoutHandler implements HttpHandler {
|
||||
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
|
||||
public LogoutHandler(Map<String, Integer> sessions, Map<String, Instant> sessionCreationTimes) {
|
||||
this.sessions = sessions;
|
||||
this.sessionCreationTimes = sessionCreationTimes;
|
||||
public LogoutHandler(Map<String, Integer> sessions, Map<String, Instant> sessionCreationTimes) {
|
||||
this.sessions = sessions;
|
||||
this.sessionCreationTimes = sessionCreationTimes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) {
|
||||
// Get session ID from cookie
|
||||
String sessionId = exchange.getRequestHeaders().getFirst("Cookie").replace("sessionID=", "");
|
||||
String currentSessionId = sessions.get(sessionId) == null ? null : sessionId;
|
||||
|
||||
// Send response
|
||||
|
||||
String response = "";
|
||||
if (currentSessionId == null) {
|
||||
response += "Session has already expired!";
|
||||
} else {
|
||||
response = "Logout successful!\n" + "Session ID: " + currentSessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) {
|
||||
// Get session ID from cookie
|
||||
String sessionID = exchange.getRequestHeaders().getFirst("Cookie").replace("sessionID=", "");
|
||||
String currentSessionID = sessions.get(sessionID) == null ? null : sessionID;
|
||||
|
||||
// Send response
|
||||
|
||||
String response = "";
|
||||
if(currentSessionID == null) {
|
||||
response += "Session has already expired!";
|
||||
} else {
|
||||
response = "Logout successful!\n" +
|
||||
"Session ID: " + currentSessionID;
|
||||
}
|
||||
|
||||
//Remove session
|
||||
if(currentSessionID != null)
|
||||
LOGGER.info("User " + sessions.get(currentSessionID) + " deleted!");
|
||||
else
|
||||
LOGGER.info("User already deleted!");
|
||||
sessions.remove(sessionID);
|
||||
sessionCreationTimes.remove(sessionID);
|
||||
|
||||
try {
|
||||
exchange.sendResponseHeaders(200, response.length());
|
||||
} catch(IOException e) {
|
||||
LOGGER.error("An error has occurred: ", e);
|
||||
}
|
||||
|
||||
try(OutputStream os = exchange.getResponseBody()) {
|
||||
os.write(response.getBytes());
|
||||
} catch(IOException e) {
|
||||
LOGGER.error("An error has occurred: ", e);
|
||||
}
|
||||
//Remove session
|
||||
if (currentSessionId != null) {
|
||||
LOGGER.info("User " + sessions.get(currentSessionId) + " deleted!");
|
||||
} else {
|
||||
LOGGER.info("User already deleted!");
|
||||
}
|
||||
sessions.remove(sessionId);
|
||||
sessionCreationTimes.remove(sessionId);
|
||||
|
||||
try {
|
||||
exchange.sendResponseHeaders(200, response.length());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("An error has occurred: ", e);
|
||||
}
|
||||
|
||||
try (OutputStream os = exchange.getResponseBody()) {
|
||||
os.write(response.getBytes());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("An error has occurred: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,59 @@
|
||||
package com.iluwatar.sessionserver;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import com.iluwatar.sessionserver.LoginHandler;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* LoginHandlerTest.
|
||||
*/
|
||||
public class LoginHandlerTest {
|
||||
|
||||
private LoginHandler loginHandler;
|
||||
//private Headers headers;
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
private LoginHandler loginHandler;
|
||||
//private Headers headers;
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
|
||||
@Mock
|
||||
private HttpExchange exchange;
|
||||
@Mock
|
||||
private HttpExchange exchange;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
sessions = new HashMap<>();
|
||||
sessionCreationTimes = new HashMap<>();
|
||||
loginHandler = new LoginHandler(sessions, sessionCreationTimes);
|
||||
}
|
||||
/**
|
||||
* Setup tests.
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
sessions = new HashMap<>();
|
||||
sessionCreationTimes = new HashMap<>();
|
||||
loginHandler = new LoginHandler(sessions, sessionCreationTimes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandle() throws IOException {
|
||||
@Test
|
||||
public void testHandle() throws IOException {
|
||||
|
||||
//assemble
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //Exchange object is mocked so OutputStream must be manually created
|
||||
when(exchange.getResponseHeaders()).thenReturn(new Headers()); //Exchange object is mocked so Header object must be manually created
|
||||
when(exchange.getResponseBody()).thenReturn(outputStream);
|
||||
//assemble
|
||||
ByteArrayOutputStream outputStream =
|
||||
new ByteArrayOutputStream(); //Exchange object is mocked so OutputStream must be manually created
|
||||
when(exchange.getResponseHeaders()).thenReturn(
|
||||
new Headers()); //Exchange object is mocked so Header object must be manually created
|
||||
when(exchange.getResponseBody()).thenReturn(outputStream);
|
||||
|
||||
//act
|
||||
loginHandler.handle(exchange);
|
||||
//act
|
||||
loginHandler.handle(exchange);
|
||||
|
||||
//assert
|
||||
String[] response = outputStream.toString().split("Session ID: ");
|
||||
assertEquals(sessions.entrySet().toArray()[0].toString().split("=1")[0], response[1]);
|
||||
}
|
||||
//assert
|
||||
String[] response = outputStream.toString().split("Session ID: ");
|
||||
assertEquals(sessions.entrySet().toArray()[0].toString().split("=1")[0], response[1]);
|
||||
}
|
||||
}
|
||||
@@ -1,75 +1,83 @@
|
||||
package com.iluwatar.sessionserver;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import com.iluwatar.sessionserver.LogoutHandler;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* LogoutHandlerTest.
|
||||
*/
|
||||
public class LogoutHandlerTest {
|
||||
|
||||
private LogoutHandler logoutHandler;
|
||||
private Headers headers;
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
private LogoutHandler logoutHandler;
|
||||
private Headers headers;
|
||||
private Map<String, Integer> sessions;
|
||||
private Map<String, Instant> sessionCreationTimes;
|
||||
|
||||
@Mock
|
||||
private HttpExchange exchange;
|
||||
@Mock
|
||||
private HttpExchange exchange;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
sessions = new HashMap<>();
|
||||
sessionCreationTimes = new HashMap<>();
|
||||
logoutHandler = new LogoutHandler(sessions, sessionCreationTimes);
|
||||
headers = new Headers();
|
||||
headers.add("Cookie", "sessionID=1234"); //Exchange object methods return Header Object but Exchange is mocked so Headers must be manually created
|
||||
}
|
||||
/**
|
||||
* Setup tests.
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
sessions = new HashMap<>();
|
||||
sessionCreationTimes = new HashMap<>();
|
||||
logoutHandler = new LogoutHandler(sessions, sessionCreationTimes);
|
||||
headers = new Headers();
|
||||
headers.add("Cookie",
|
||||
"sessionID=1234"); //Exchange object methods return Header Object but Exchange is mocked so Headers must be manually created
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandler_SessionNotExpired() throws IOException {
|
||||
@Test
|
||||
public void testHandler_SessionNotExpired() throws IOException {
|
||||
|
||||
//assemble
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
sessions.put("1234", 1); //Fake login details since LoginHandler isn't called
|
||||
sessionCreationTimes.put("1234", Instant.now()); //Fake login details since LoginHandler isn't called
|
||||
when(exchange.getRequestHeaders()).thenReturn(headers);
|
||||
when(exchange.getResponseBody()).thenReturn(outputStream);
|
||||
//assemble
|
||||
sessions.put("1234", 1); //Fake login details since LoginHandler isn't called
|
||||
sessionCreationTimes.put("1234",
|
||||
Instant.now()); //Fake login details since LoginHandler isn't called
|
||||
when(exchange.getRequestHeaders()).thenReturn(headers);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
when(exchange.getResponseBody()).thenReturn(outputStream);
|
||||
|
||||
//act
|
||||
logoutHandler.handle(exchange);
|
||||
//act
|
||||
logoutHandler.handle(exchange);
|
||||
|
||||
//assert
|
||||
String[] response = outputStream.toString().split("Session ID: ");
|
||||
Assertions.assertEquals("1234", response[1]);
|
||||
Assertions.assertFalse(sessions.containsKey(response));
|
||||
Assertions.assertFalse(sessionCreationTimes.containsKey(response));
|
||||
}
|
||||
//assert
|
||||
String[] response = outputStream.toString().split("Session ID: ");
|
||||
Assertions.assertEquals("1234", response[1]);
|
||||
Assertions.assertFalse(sessions.containsKey(response));
|
||||
Assertions.assertFalse(sessionCreationTimes.containsKey(response));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandler_SessionExpired() throws IOException {
|
||||
@Test
|
||||
public void testHandler_SessionExpired() throws IOException {
|
||||
|
||||
//assemble
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
when(exchange.getRequestHeaders()).thenReturn(headers);
|
||||
when(exchange.getResponseBody()).thenReturn(outputStream);
|
||||
//assemble
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
when(exchange.getRequestHeaders()).thenReturn(headers);
|
||||
when(exchange.getResponseBody()).thenReturn(outputStream);
|
||||
|
||||
//act
|
||||
logoutHandler.handle(exchange);
|
||||
//act
|
||||
logoutHandler.handle(exchange);
|
||||
|
||||
//assert
|
||||
String[] response = outputStream.toString().split("Session ID: ");
|
||||
Assertions.assertEquals("Session has already expired!", response[0]);
|
||||
Assertions.assertFalse(sessions.containsKey(response));
|
||||
Assertions.assertFalse(sessionCreationTimes.containsKey(response));
|
||||
}
|
||||
//assert
|
||||
String[] response = outputStream.toString().split("Session ID: ");
|
||||
Assertions.assertEquals("Session has already expired!", response[0]);
|
||||
Assertions.assertFalse(sessions.containsKey(response));
|
||||
Assertions.assertFalse(sessionCreationTimes.containsKey(response));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user