package org.glassfish.grizzly.http.server;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.glassfish.grizzly.http.Cookie;
import org.glassfish.grizzly.http.server.util.Globals;
public class DefaultSessionManager implements SessionManager {
public static SessionManager instance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final DefaultSessionManager INSTANCE = new DefaultSessionManager();
}
private final ConcurrentMap<String, Session> sessions = new ConcurrentHashMap<>();
private final Random rnd = new Random();
private String sessionCookieName = Globals.SESSION_COOKIE_NAME;
private final ScheduledThreadPoolExecutor sessionExpirer = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
final Thread t = new Thread(r, "Grizzly-HttpSession-Expirer");
t.setDaemon(true);
return t;
}
});
{
sessionExpirer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
long currentTime = System.currentTimeMillis();
Iterator<Map.Entry<String, Session>> iterator = sessions.entrySet().iterator();
Map.Entry<String, Session> entry;
while (iterator.hasNext()) {
entry = iterator.next();
final Session session = entry.getValue();
if (!session.isValid() || session.getSessionTimeout() > 0 && currentTime - session.getTimestamp() > session.getSessionTimeout()) {
session.setValid(false);
iterator.remove();
}
}
}
}, 5, 5, TimeUnit.SECONDS);
}
private DefaultSessionManager() {
}
@Override
public Session getSession(final Request request, String requestedSessionId) {
if (requestedSessionId != null) {
final Session session = sessions.get(requestedSessionId);
if (session != null && session.isValid()) {
return session;
}
}
return null;
}
@Override
public Session createSession(final Request request) {
final Session session = new Session();
String requestedSessionId;
do {
requestedSessionId = String.valueOf(generateRandomLong());
session.setIdInternal(requestedSessionId);
} while (sessions.putIfAbsent(requestedSessionId, session) != null);
return session;
}
@Override
public String changeSessionId(final Request request, final Session session) {
final String oldSessionId = session.getIdInternal();
final String newSessionId = String.valueOf(generateRandomLong());
session.setIdInternal(newSessionId);
sessions.remove(oldSessionId);
sessions.put(newSessionId, session);
return oldSessionId;
}
@Override
public void configureSessionCookie(final Request request, final Cookie cookie) {
}
@Override
public void setSessionCookieName(final String name) {
if (name != null && !name.isEmpty()) {
sessionCookieName = name;
}
}
@Override
public String getSessionCookieName() {
return sessionCookieName;
}
private long generateRandomLong() {
return rnd.nextLong() & 0x7FFFFFFFFFFFFFFFL;
}
}