Bug fixes and added redis sentinel supportability changes.
parent
f48861ad95
commit
c4f205cb51
|
@ -74,5 +74,4 @@ public class SerializationUtil {
|
||||||
session.readObjectData(ois);
|
session.readObjectData(ois);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@ public class Session extends StandardSession {
|
||||||
|
|
||||||
private static final long serialVersionUID = -6056744304016869278L;
|
private static final long serialVersionUID = -6056744304016869278L;
|
||||||
|
|
||||||
protected Boolean dirty;
|
private Boolean dirty;
|
||||||
protected Map<String, Object> changedAttributes;
|
private Map<String, Object> changedAttributes;
|
||||||
|
|
||||||
protected static Boolean manualDirtyTrackingSupportEnabled = false;
|
private static Boolean manualDirtyTrackingSupportEnabled = false;
|
||||||
protected static String manualDirtyTrackingAttributeKey = "__changed__";
|
private static String manualDirtyTrackingAttributeKey = "__changed__";
|
||||||
|
|
||||||
public Session(Manager manager) {
|
public Session(Manager manager) {
|
||||||
super(manager);
|
super(manager);
|
||||||
|
@ -131,5 +131,4 @@ public class Session extends StandardSession {
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
super.invalidate();
|
super.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,5 +18,4 @@ public interface SessionConstants {
|
||||||
throw new IllegalArgumentException("Invalid session policy [" + name + "]");
|
throw new IllegalArgumentException("Invalid session policy [" + name + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,5 +53,4 @@ public class SessionContext {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SessionContext [id=" + id + "]";
|
return "SessionContext [id=" + id + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,5 +44,4 @@ public class SessionMetadata implements Serializable {
|
||||||
in.read(attributesHash, 0, hashLength);
|
in.read(attributesHash, 0, hashLength);
|
||||||
this.attributesHash = attributesHash;
|
this.attributesHash = attributesHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,5 +45,4 @@ public interface DataCache {
|
||||||
* @return - Returns the number of keys that were removed.
|
* @return - Returns the number of keys that were removed.
|
||||||
*/
|
*/
|
||||||
Long delete(String key);
|
Long delete(String key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package tomcat.request.session.data.cache;
|
||||||
|
|
||||||
|
/** author: Ranjith Manickam @ 3 Dec' 2018 */
|
||||||
|
public interface DataCacheConstants {
|
||||||
|
|
||||||
|
// redis properties file name
|
||||||
|
String APPLICATION_PROPERTIES_FILE = "redis-data-cache.properties";
|
||||||
|
|
||||||
|
// redis properties
|
||||||
|
String REDIS_HOSTS = "redis.hosts:127.0.0.1:6379";
|
||||||
|
String REDIS_CLUSTER_ENABLED = "redis.cluster.enabled:false";
|
||||||
|
String REDIS_SENTINEL_ENABLED = "redis.sentinel.enabled:false";
|
||||||
|
String REDIS_LB_STICKY_SESSION_ENABLED = "redis.load-balancer.sticky-session.enabled:false";
|
||||||
|
|
||||||
|
String REDIS_MAX_ACTIVE = "redis.max.active:10";
|
||||||
|
String REDIS_TEST_ONBORROW = "redis.test.onBorrow:true";
|
||||||
|
String REDIS_TEST_ONRETURN = "redis.test.onReturn:true";
|
||||||
|
String REDIS_MAX_IDLE = "redis.max.idle:5";
|
||||||
|
String REDIS_MIN_IDLE = "redis.min.idle:1";
|
||||||
|
String REDIS_TEST_WHILEIDLE = "redis.test.whileIdle:true";
|
||||||
|
String REDIS_TEST_NUMPEREVICTION = "redis.test.numPerEviction:10";
|
||||||
|
String REDIS_TIME_BETWEENEVICTION = "redis.time.betweenEviction:60000";
|
||||||
|
|
||||||
|
String REDIS_PASSWORD = "redis.password";
|
||||||
|
String REDIS_DATABASE = "redis.database";
|
||||||
|
String REDIS_TIMEOUT = "redis.timeout";
|
||||||
|
|
||||||
|
String REDIS_SENTINEL_MASTER = "redis.sentinel.master";
|
||||||
|
String REDIS_DEFAULT_SENTINEL_MASTER = "mymaster";
|
||||||
|
|
||||||
|
String REDIS_CONN_FAILED_RETRY_MSG = "Jedis connection failed, retrying...";
|
||||||
|
|
||||||
|
enum RedisConfigType {
|
||||||
|
DEFAULT,
|
||||||
|
SENTINEL,
|
||||||
|
CLUSTER
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package tomcat.request.session.data.cache;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import tomcat.request.session.SessionConstants;
|
||||||
|
import tomcat.request.session.data.cache.impl.StandardDataCache;
|
||||||
|
import tomcat.request.session.data.cache.impl.redis.RedisCache;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/** author: Ranjith Manickam @ 3 Dec' 2018 */
|
||||||
|
public class DataCacheFactory {
|
||||||
|
|
||||||
|
private static final Log LOGGER = LogFactory.getLog(DataCacheFactory.class);
|
||||||
|
|
||||||
|
private final long sessionExpiryTime;
|
||||||
|
|
||||||
|
public DataCacheFactory(long sessionExpiryTime) {
|
||||||
|
this.sessionExpiryTime = sessionExpiryTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** To get data cache. */
|
||||||
|
public DataCache getDataCache() {
|
||||||
|
Properties properties = getApplicationProperties();
|
||||||
|
|
||||||
|
if (Boolean.valueOf(getProperty(properties, DataCacheConstants.REDIS_LB_STICKY_SESSION_ENABLED))) {
|
||||||
|
return new StandardDataCache(properties, this.sessionExpiryTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RedisCache(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** To get redis data cache properties. */
|
||||||
|
private Properties getApplicationProperties() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
try {
|
||||||
|
String filePath = System.getProperty(SessionConstants.CATALINA_BASE).concat(File.separator)
|
||||||
|
.concat(SessionConstants.CONF).concat(File.separator)
|
||||||
|
.concat(DataCacheConstants.APPLICATION_PROPERTIES_FILE);
|
||||||
|
|
||||||
|
InputStream resourceStream = null;
|
||||||
|
try {
|
||||||
|
resourceStream = (!filePath.isEmpty() && new File(filePath).exists()) ? new FileInputStream(filePath) : null;
|
||||||
|
if (resourceStream == null) {
|
||||||
|
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
|
resourceStream = loader.getResourceAsStream(DataCacheConstants.APPLICATION_PROPERTIES_FILE);
|
||||||
|
}
|
||||||
|
properties.load(resourceStream);
|
||||||
|
} finally {
|
||||||
|
if (resourceStream != null) {
|
||||||
|
resourceStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.error("Error while retrieving application properties", ex);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To get property with the specified key in this properties list.
|
||||||
|
*
|
||||||
|
* @param properties - properties list.
|
||||||
|
* @param key - search key.
|
||||||
|
* @return - Returns the property value.
|
||||||
|
*/
|
||||||
|
public static String getProperty(Properties properties, String key) {
|
||||||
|
return getProperty(properties, key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To get property with the specified key in this properties list.
|
||||||
|
*
|
||||||
|
* @param properties - properties list.
|
||||||
|
* @param key - search key.
|
||||||
|
* @param defaultValue - default value.
|
||||||
|
* @return - - Returns the property value.
|
||||||
|
*/
|
||||||
|
public static String getProperty(Properties properties, String key, String defaultValue) {
|
||||||
|
String[] keyValue = key.split(":");
|
||||||
|
return properties.getProperty(keyValue[0], (keyValue.length > 1 && defaultValue == null) ? keyValue[1] : defaultValue);
|
||||||
|
}
|
||||||
|
}
|
142
src/main/java/tomcat/request/session/data/cache/impl/StandardDataCache.java
vendored
Normal file
142
src/main/java/tomcat/request/session/data/cache/impl/StandardDataCache.java
vendored
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
package tomcat.request.session.data.cache.impl;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import tomcat.request.session.data.cache.impl.redis.RedisCache;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/** author: Ranjith Manickam @ 3 Dec' 2018 */
|
||||||
|
public class StandardDataCache extends RedisCache {
|
||||||
|
|
||||||
|
private Date lastSessionJobRun;
|
||||||
|
private final Map<String, SessionData> sessionData = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final long sessionExpiryTime;
|
||||||
|
|
||||||
|
public StandardDataCache(Properties properties, long sessionExpiryTime) {
|
||||||
|
super(properties);
|
||||||
|
this.sessionExpiryTime = (sessionExpiryTime + 60) / 60;
|
||||||
|
this.lastSessionJobRun = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public byte[] set(String key, byte[] value) {
|
||||||
|
triggerSessionExpiry();
|
||||||
|
this.sessionData.put(key, new SessionData(value));
|
||||||
|
return super.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public Long setnx(String key, byte[] value) {
|
||||||
|
triggerSessionExpiry();
|
||||||
|
Long retValue = super.setnx(key, value);
|
||||||
|
if (retValue == 1L) {
|
||||||
|
this.sessionData.put(key, new SessionData(value));
|
||||||
|
}
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public Long expire(String key, int seconds) {
|
||||||
|
return super.expire(key, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public byte[] get(String key) {
|
||||||
|
triggerSessionExpiry();
|
||||||
|
if (this.sessionData.containsKey(key)) {
|
||||||
|
return this.sessionData.get(key).getValue();
|
||||||
|
}
|
||||||
|
return super.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public Long delete(String key) {
|
||||||
|
this.sessionData.remove(key);
|
||||||
|
return super.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Session data. */
|
||||||
|
private class SessionData implements Serializable {
|
||||||
|
private byte[] value;
|
||||||
|
private Date lastAccessedOn;
|
||||||
|
|
||||||
|
SessionData(byte[] value) {
|
||||||
|
this.value = value;
|
||||||
|
updatedLastAccessedOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatedLastAccessedOn() {
|
||||||
|
this.lastAccessedOn = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] getValue() {
|
||||||
|
updatedLastAccessedOn();
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Date getLastAccessedOn() {
|
||||||
|
return this.lastAccessedOn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** To trigger session expiry thread. */
|
||||||
|
private void triggerSessionExpiry() {
|
||||||
|
long diff = new Date().getTime() - this.lastSessionJobRun.getTime();
|
||||||
|
long diffMinutes = diff / (60 * 1000) % 60;
|
||||||
|
|
||||||
|
if (diffMinutes > 0L) {
|
||||||
|
synchronized (this) {
|
||||||
|
new SessionDataExpiryThread(this.sessionData, this.sessionExpiryTime);
|
||||||
|
this.lastSessionJobRun = new Date();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Session data expiry thread. This will takes care of the session expired data removal. */
|
||||||
|
private class SessionDataExpiryThread implements Runnable {
|
||||||
|
|
||||||
|
private final Log LOGGER = LogFactory.getLog(SessionDataExpiryThread.class);
|
||||||
|
|
||||||
|
private final long sessionExpiryTime;
|
||||||
|
private final Map<String, SessionData> sessionData;
|
||||||
|
|
||||||
|
SessionDataExpiryThread(Map<String, SessionData> sessionData, long sessionExpiryTime) {
|
||||||
|
this.sessionData = sessionData;
|
||||||
|
this.sessionExpiryTime = sessionExpiryTime;
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
for (String key : this.sessionData.keySet()) {
|
||||||
|
SessionData data = this.sessionData.get(key);
|
||||||
|
if (data == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
long diff = new Date().getTime() - data.getLastAccessedOn().getTime();
|
||||||
|
long diffMinutes = diff / (60 * 1000) % 60;
|
||||||
|
|
||||||
|
if (diffMinutes > this.sessionExpiryTime) {
|
||||||
|
this.sessionData.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOGGER.error("Error processing session data expiry thread", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,13 @@
|
||||||
package tomcat.request.session.data.cache.impl.redis;
|
package tomcat.request.session.data.cache.impl.redis;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import redis.clients.jedis.HostAndPort;
|
import redis.clients.jedis.HostAndPort;
|
||||||
import redis.clients.jedis.JedisPoolConfig;
|
import redis.clients.jedis.JedisPoolConfig;
|
||||||
import redis.clients.jedis.Protocol;
|
import redis.clients.jedis.Protocol;
|
||||||
import tomcat.request.session.SessionConstants;
|
|
||||||
import tomcat.request.session.data.cache.DataCache;
|
import tomcat.request.session.data.cache.DataCache;
|
||||||
import tomcat.request.session.data.cache.impl.redis.RedisConstants.RedisConfigType;
|
import tomcat.request.session.data.cache.DataCacheConstants;
|
||||||
|
import tomcat.request.session.data.cache.DataCacheConstants.RedisConfigType;
|
||||||
|
import tomcat.request.session.data.cache.DataCacheFactory;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -23,12 +18,10 @@ import java.util.Set;
|
||||||
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
||||||
public class RedisCache implements DataCache {
|
public class RedisCache implements DataCache {
|
||||||
|
|
||||||
private static DataCache dataCache;
|
private DataCache dataCache;
|
||||||
|
|
||||||
private static final Log LOGGER = LogFactory.getLog(RedisCache.class);
|
public RedisCache(Properties properties) {
|
||||||
|
initialize(properties);
|
||||||
public RedisCache() {
|
|
||||||
initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
@ -61,44 +54,38 @@ public class RedisCache implements DataCache {
|
||||||
return dataCache.delete(key);
|
return dataCache.delete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** To initialize the redis data cache. */
|
private void initialize(Properties properties) {
|
||||||
private void initialize() {
|
|
||||||
if (dataCache != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Properties properties = getProperties();
|
|
||||||
|
|
||||||
RedisConfigType configType;
|
RedisConfigType configType;
|
||||||
if (Boolean.valueOf(properties.getProperty(RedisConstants.CLUSTER_ENABLED))) {
|
if (Boolean.valueOf(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_CLUSTER_ENABLED))) {
|
||||||
configType = RedisConfigType.CLUSTER;
|
configType = RedisConfigType.CLUSTER;
|
||||||
} else if (Boolean.valueOf(properties.getProperty(RedisConstants.SENTINEL_ENABLED))) {
|
} else if (Boolean.valueOf(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_SENTINEL_ENABLED))) {
|
||||||
configType = RedisConfigType.SENTINEL;
|
configType = RedisConfigType.SENTINEL;
|
||||||
} else {
|
} else {
|
||||||
configType = RedisConfigType.DEFAULT;
|
configType = RedisConfigType.DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
String hosts = properties.getProperty(RedisConstants.HOSTS, Protocol.DEFAULT_HOST.concat(":").concat(String.valueOf(Protocol.DEFAULT_PORT)));
|
String hosts = DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_HOSTS, String.format("%s:%s", Protocol.DEFAULT_HOST, Protocol.DEFAULT_PORT));
|
||||||
Collection<?> nodes = getJedisNodes(hosts, configType);
|
Collection<?> nodes = getJedisNodes(hosts, configType);
|
||||||
|
|
||||||
String password = properties.getProperty(RedisConstants.PASSWORD);
|
String password = DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_PASSWORD);
|
||||||
password = (password != null && !password.isEmpty()) ? password : null;
|
password = (password != null && !password.isEmpty()) ? password : null;
|
||||||
|
|
||||||
int database = Integer.parseInt(properties.getProperty(RedisConstants.DATABASE, String.valueOf(Protocol.DEFAULT_DATABASE)));
|
int database = Integer.parseInt(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_DATABASE));
|
||||||
|
|
||||||
int timeout = Integer.parseInt(properties.getProperty(RedisConstants.TIMEOUT, String.valueOf(Protocol.DEFAULT_TIMEOUT)));
|
int timeout = Integer.parseInt(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_TIMEOUT));
|
||||||
timeout = (timeout < Protocol.DEFAULT_TIMEOUT) ? Protocol.DEFAULT_TIMEOUT : timeout;
|
timeout = (timeout < Protocol.DEFAULT_TIMEOUT) ? Protocol.DEFAULT_TIMEOUT : timeout;
|
||||||
|
|
||||||
JedisPoolConfig poolConfig = getPoolConfig(properties);
|
JedisPoolConfig poolConfig = getPoolConfig(properties);
|
||||||
switch (configType) {
|
switch (configType) {
|
||||||
case CLUSTER:
|
case CLUSTER:
|
||||||
dataCache = new RedisClusterUtil((Set<HostAndPort>) nodes, password, timeout, poolConfig);
|
dataCache = new RedisClusterManager((Set<HostAndPort>) nodes, password, timeout, poolConfig);
|
||||||
break;
|
break;
|
||||||
case SENTINEL:
|
case SENTINEL:
|
||||||
String masterName = String.valueOf(properties.getProperty(RedisConstants.SENTINEL_MASTER, RedisConstants.DEFAULT_SENTINEL_MASTER));
|
String masterName = String.valueOf(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_SENTINEL_MASTER));
|
||||||
dataCache = new RedisSentinelUtil((Set<String>) nodes, masterName, password, database, timeout, poolConfig);
|
dataCache = new RedisSentinelManager((Set<String>) nodes, masterName, password, database, timeout, poolConfig);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dataCache = new RedisUtil(((List<String>) nodes).get(0), Integer.parseInt(((List<String>) nodes).get(1)), password, database, timeout, poolConfig);
|
dataCache = new RedisStandardManager(((List<String>) nodes).get(0), Integer.parseInt(((List<String>) nodes).get(1)), password, database, timeout, poolConfig);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,28 +98,28 @@ public class RedisCache implements DataCache {
|
||||||
*/
|
*/
|
||||||
private JedisPoolConfig getPoolConfig(Properties properties) {
|
private JedisPoolConfig getPoolConfig(Properties properties) {
|
||||||
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
||||||
int maxActive = Integer.parseInt(properties.getProperty(RedisConstants.MAX_ACTIVE, RedisConstants.DEFAULT_MAX_ACTIVE_VALUE));
|
int maxActive = Integer.parseInt(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_MAX_ACTIVE));
|
||||||
poolConfig.setMaxTotal(maxActive);
|
poolConfig.setMaxTotal(maxActive);
|
||||||
|
|
||||||
boolean testOnBorrow = Boolean.parseBoolean(properties.getProperty(RedisConstants.TEST_ONBORROW, RedisConstants.DEFAULT_TEST_ONBORROW_VALUE));
|
boolean testOnBorrow = Boolean.parseBoolean(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_TEST_ONBORROW));
|
||||||
poolConfig.setTestOnBorrow(testOnBorrow);
|
poolConfig.setTestOnBorrow(testOnBorrow);
|
||||||
|
|
||||||
boolean testOnReturn = Boolean.parseBoolean(properties.getProperty(RedisConstants.TEST_ONRETURN, RedisConstants.DEFAULT_TEST_ONRETURN_VALUE));
|
boolean testOnReturn = Boolean.parseBoolean(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_TEST_ONRETURN));
|
||||||
poolConfig.setTestOnReturn(testOnReturn);
|
poolConfig.setTestOnReturn(testOnReturn);
|
||||||
|
|
||||||
int maxIdle = Integer.parseInt(properties.getProperty(RedisConstants.MAX_ACTIVE, RedisConstants.DEFAULT_MAX_ACTIVE_VALUE));
|
int maxIdle = Integer.parseInt(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_MAX_ACTIVE));
|
||||||
poolConfig.setMaxIdle(maxIdle);
|
poolConfig.setMaxIdle(maxIdle);
|
||||||
|
|
||||||
int minIdle = Integer.parseInt(properties.getProperty(RedisConstants.MIN_IDLE, RedisConstants.DEFAULT_MIN_IDLE_VALUE));
|
int minIdle = Integer.parseInt(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_MIN_IDLE));
|
||||||
poolConfig.setMinIdle(minIdle);
|
poolConfig.setMinIdle(minIdle);
|
||||||
|
|
||||||
boolean testWhileIdle = Boolean.parseBoolean(properties.getProperty(RedisConstants.TEST_WHILEIDLE, RedisConstants.DEFAULT_TEST_WHILEIDLE_VALUE));
|
boolean testWhileIdle = Boolean.parseBoolean(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_TEST_WHILEIDLE));
|
||||||
poolConfig.setTestWhileIdle(testWhileIdle);
|
poolConfig.setTestWhileIdle(testWhileIdle);
|
||||||
|
|
||||||
int testNumPerEviction = Integer.parseInt(properties.getProperty(RedisConstants.TEST_NUMPEREVICTION, RedisConstants.DEFAULT_TEST_NUMPEREVICTION_VALUE));
|
int testNumPerEviction = Integer.parseInt(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_TEST_NUMPEREVICTION));
|
||||||
poolConfig.setNumTestsPerEvictionRun(testNumPerEviction);
|
poolConfig.setNumTestsPerEvictionRun(testNumPerEviction);
|
||||||
|
|
||||||
long timeBetweenEviction = Long.parseLong(properties.getProperty(RedisConstants.TIME_BETWEENEVICTION, RedisConstants.DEFAULT_TIME_BETWEENEVICTION_VALUE));
|
long timeBetweenEviction = Long.parseLong(DataCacheFactory.getProperty(properties, DataCacheConstants.REDIS_TIME_BETWEENEVICTION));
|
||||||
poolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEviction);
|
poolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEviction);
|
||||||
return poolConfig;
|
return poolConfig;
|
||||||
}
|
}
|
||||||
|
@ -174,33 +161,4 @@ public class RedisCache implements DataCache {
|
||||||
}
|
}
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** To get redis data cache properties. */
|
|
||||||
private Properties getProperties() {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
try {
|
|
||||||
String filePath = System.getProperty(SessionConstants.CATALINA_BASE).concat(File.separator)
|
|
||||||
.concat(SessionConstants.CONF).concat(File.separator)
|
|
||||||
.concat(RedisConstants.PROPERTIES_FILE);
|
|
||||||
|
|
||||||
InputStream resourceStream = null;
|
|
||||||
try {
|
|
||||||
resourceStream = (!filePath.isEmpty() && new File(filePath).exists()) ? new FileInputStream(filePath) : null;
|
|
||||||
|
|
||||||
if (resourceStream == null) {
|
|
||||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
|
||||||
resourceStream = loader.getResourceAsStream(RedisConstants.PROPERTIES_FILE);
|
|
||||||
}
|
|
||||||
properties.load(resourceStream);
|
|
||||||
} finally {
|
|
||||||
if (resourceStream != null) {
|
|
||||||
resourceStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.error("Error while loading task scheduler properties", ex);
|
|
||||||
}
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
||||||
public class RedisClusterUtil extends AbstractRedisUtil {
|
class RedisClusterManager extends RedisManager {
|
||||||
|
|
||||||
private final JedisCluster cluster;
|
private final JedisCluster cluster;
|
||||||
|
|
||||||
|
@ -18,13 +18,12 @@ public class RedisClusterUtil extends AbstractRedisUtil {
|
||||||
private static final int DEFAULT_MAX_REDIRECTIONS = 5;
|
private static final int DEFAULT_MAX_REDIRECTIONS = 5;
|
||||||
private static final long FAILIURE_WAIT_TIME = 4000L;
|
private static final long FAILIURE_WAIT_TIME = 4000L;
|
||||||
|
|
||||||
RedisClusterUtil(Set<HostAndPort> nodes,
|
RedisClusterManager(Set<HostAndPort> nodes,
|
||||||
String password,
|
String password,
|
||||||
int timeout,
|
int timeout,
|
||||||
JedisPoolConfig poolConfig) {
|
JedisPoolConfig poolConfig) {
|
||||||
super(null, FAILIURE_WAIT_TIME);
|
super(null, FAILIURE_WAIT_TIME);
|
||||||
this.cluster = new JedisCluster(nodes, timeout, Protocol.DEFAULT_TIMEOUT, DEFAULT_MAX_REDIRECTIONS,
|
this.cluster = new JedisCluster(nodes, timeout, Protocol.DEFAULT_TIMEOUT, DEFAULT_MAX_REDIRECTIONS, password, poolConfig);
|
||||||
password, poolConfig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
@ -116,5 +115,4 @@ public class RedisClusterUtil extends AbstractRedisUtil {
|
||||||
} while (retry && tries <= NUM_RETRIES);
|
} while (retry && tries <= NUM_RETRIES);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,48 +0,0 @@
|
||||||
package tomcat.request.session.data.cache.impl.redis;
|
|
||||||
|
|
||||||
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
|
||||||
interface RedisConstants {
|
|
||||||
|
|
||||||
// redis properties file name
|
|
||||||
String PROPERTIES_FILE = "redis-data-cache.properties";
|
|
||||||
|
|
||||||
// redis properties
|
|
||||||
String HOSTS = "redis.hosts";
|
|
||||||
String CLUSTER_ENABLED = "redis.cluster.enabled";
|
|
||||||
String SENTINEL_ENABLED = "redis.sentinel.enabled";
|
|
||||||
|
|
||||||
String MAX_ACTIVE = "redis.max.active";
|
|
||||||
String TEST_ONBORROW = "redis.test.onBorrow";
|
|
||||||
String TEST_ONRETURN = "redis.test.onReturn";
|
|
||||||
String MAX_IDLE = "redis.max.idle";
|
|
||||||
String MIN_IDLE = "redis.min.idle";
|
|
||||||
String TEST_WHILEIDLE = "redis.test.whileIdle";
|
|
||||||
String TEST_NUMPEREVICTION = "redis.test.numPerEviction";
|
|
||||||
String TIME_BETWEENEVICTION = "redis.time.betweenEviction";
|
|
||||||
|
|
||||||
String PASSWORD = "redis.password";
|
|
||||||
String DATABASE = "redis.database";
|
|
||||||
String TIMEOUT = "redis.timeout";
|
|
||||||
|
|
||||||
String SENTINEL_MASTER = "redis.sentinel.master";
|
|
||||||
String DEFAULT_SENTINEL_MASTER = "mymaster";
|
|
||||||
|
|
||||||
// redis property default values
|
|
||||||
String DEFAULT_MAX_ACTIVE_VALUE = "10";
|
|
||||||
String DEFAULT_TEST_ONBORROW_VALUE = "true";
|
|
||||||
String DEFAULT_TEST_ONRETURN_VALUE = "true";
|
|
||||||
String DEFAULT_MAX_IDLE_VALUE = "5";
|
|
||||||
String DEFAULT_MIN_IDLE_VALUE = "1";
|
|
||||||
String DEFAULT_TEST_WHILEIDLE_VALUE = "true";
|
|
||||||
String DEFAULT_TEST_NUMPEREVICTION_VALUE = "10";
|
|
||||||
String DEFAULT_TIME_BETWEENEVICTION_VALUE = "60000";
|
|
||||||
|
|
||||||
String CONN_FAILED_RETRY_MSG = "Jedis connection failed, retrying...";
|
|
||||||
|
|
||||||
enum RedisConfigType {
|
|
||||||
DEFAULT,
|
|
||||||
SENTINEL,
|
|
||||||
CLUSTER
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -6,17 +6,18 @@ import redis.clients.jedis.Jedis;
|
||||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
import redis.clients.util.Pool;
|
import redis.clients.util.Pool;
|
||||||
import tomcat.request.session.data.cache.DataCache;
|
import tomcat.request.session.data.cache.DataCache;
|
||||||
|
import tomcat.request.session.data.cache.DataCacheConstants;
|
||||||
|
|
||||||
/** author: Ranjith Manickam @ 3 Dec' 2018 */
|
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
||||||
public abstract class AbstractRedisUtil implements DataCache {
|
abstract class RedisManager implements DataCache {
|
||||||
|
|
||||||
private static final int NUM_RETRIES = 3;
|
private static final int NUM_RETRIES = 3;
|
||||||
private static final Log LOGGER = LogFactory.getLog(RedisUtil.class);
|
private static final Log LOGGER = LogFactory.getLog(RedisManager.class);
|
||||||
|
|
||||||
private final Pool<Jedis> pool;
|
private final Pool<Jedis> pool;
|
||||||
private final long failiureWaitTime;
|
private final long failiureWaitTime;
|
||||||
|
|
||||||
AbstractRedisUtil(Pool<Jedis> pool, long failiureWaitTime) {
|
RedisManager(Pool<Jedis> pool, long failiureWaitTime) {
|
||||||
this.pool = pool;
|
this.pool = pool;
|
||||||
this.failiureWaitTime = failiureWaitTime;
|
this.failiureWaitTime = failiureWaitTime;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +119,7 @@ public abstract class AbstractRedisUtil implements DataCache {
|
||||||
* @param ex - jedis exception.
|
* @param ex - jedis exception.
|
||||||
*/
|
*/
|
||||||
void handleException(int tries, RuntimeException ex) {
|
void handleException(int tries, RuntimeException ex) {
|
||||||
LOGGER.error(RedisConstants.CONN_FAILED_RETRY_MSG + tries);
|
LOGGER.error(DataCacheConstants.REDIS_CONN_FAILED_RETRY_MSG + tries);
|
||||||
if (tries == NUM_RETRIES) {
|
if (tries == NUM_RETRIES) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
@ -128,5 +129,4 @@ public abstract class AbstractRedisUtil implements DataCache {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -6,17 +6,16 @@ import redis.clients.jedis.JedisSentinelPool;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/** author: Ranjith Manickam @ 3 Dec' 2018 */
|
/** author: Ranjith Manickam @ 3 Dec' 2018 */
|
||||||
class RedisSentinelUtil extends AbstractRedisUtil {
|
class RedisSentinelManager extends RedisManager {
|
||||||
|
|
||||||
private static final long FAILIURE_WAIT_TIME = 2000L;
|
private static final long FAILIURE_WAIT_TIME = 2000L;
|
||||||
|
|
||||||
RedisSentinelUtil(Set<String> nodes,
|
RedisSentinelManager(Set<String> nodes,
|
||||||
String masterName,
|
String masterName,
|
||||||
String password,
|
String password,
|
||||||
int database,
|
int database,
|
||||||
int timeout,
|
int timeout,
|
||||||
JedisPoolConfig poolConfig) {
|
JedisPoolConfig poolConfig) {
|
||||||
super(new JedisSentinelPool(masterName, nodes, poolConfig, timeout, password, database), FAILIURE_WAIT_TIME);
|
super(new JedisSentinelPool(masterName, nodes, poolConfig, timeout, password, database), FAILIURE_WAIT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,17 +4,16 @@ import redis.clients.jedis.JedisPool;
|
||||||
import redis.clients.jedis.JedisPoolConfig;
|
import redis.clients.jedis.JedisPoolConfig;
|
||||||
|
|
||||||
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
/** author: Ranjith Manickam @ 12 Jul' 2018 */
|
||||||
class RedisUtil extends AbstractRedisUtil {
|
class RedisStandardManager extends RedisManager {
|
||||||
|
|
||||||
private static final long FAILIURE_WAIT_TIME = 2000L;
|
private static final long FAILIURE_WAIT_TIME = 2000L;
|
||||||
|
|
||||||
RedisUtil(String host,
|
RedisStandardManager(String host,
|
||||||
int port,
|
int port,
|
||||||
String password,
|
String password,
|
||||||
int database,
|
int database,
|
||||||
int timeout,
|
int timeout,
|
||||||
JedisPoolConfig poolConfig) {
|
JedisPoolConfig poolConfig) {
|
||||||
super(new JedisPool(poolConfig, host, port, timeout, password, database), FAILIURE_WAIT_TIME);
|
super(new JedisPool(poolConfig, host, port, timeout, password, database), FAILIURE_WAIT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@ public class SessionHandlerValve extends ValveBase {
|
||||||
private SessionManager manager;
|
private SessionManager manager;
|
||||||
|
|
||||||
/** To set session manager */
|
/** To set session manager */
|
||||||
public void setSessionManager(SessionManager manager) {
|
void setSessionManager(SessionManager manager) {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,7 @@ public class SessionHandlerValve extends ValveBase {
|
||||||
LOGGER.error("Error processing request", ex);
|
LOGGER.error("Error processing request", ex);
|
||||||
throw new BackendException();
|
throw new BackendException();
|
||||||
} finally {
|
} finally {
|
||||||
manager.afterRequest(request);
|
manager.afterRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import org.apache.catalina.LifecycleException;
|
||||||
import org.apache.catalina.LifecycleListener;
|
import org.apache.catalina.LifecycleListener;
|
||||||
import org.apache.catalina.LifecycleState;
|
import org.apache.catalina.LifecycleState;
|
||||||
import org.apache.catalina.Valve;
|
import org.apache.catalina.Valve;
|
||||||
import org.apache.catalina.connector.Request;
|
|
||||||
import org.apache.catalina.session.ManagerBase;
|
import org.apache.catalina.session.ManagerBase;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -17,7 +16,7 @@ import tomcat.request.session.SessionConstants.SessionPolicy;
|
||||||
import tomcat.request.session.SessionContext;
|
import tomcat.request.session.SessionContext;
|
||||||
import tomcat.request.session.SessionMetadata;
|
import tomcat.request.session.SessionMetadata;
|
||||||
import tomcat.request.session.data.cache.DataCache;
|
import tomcat.request.session.data.cache.DataCache;
|
||||||
import tomcat.request.session.data.cache.impl.redis.RedisCache;
|
import tomcat.request.session.data.cache.DataCacheFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
@ -29,42 +28,17 @@ import java.util.Set;
|
||||||
public class SessionManager extends ManagerBase implements Lifecycle {
|
public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
|
|
||||||
private DataCache dataCache;
|
private DataCache dataCache;
|
||||||
protected SerializationUtil serializer;
|
private SerializationUtil serializer;
|
||||||
protected SessionHandlerValve handlerValve;
|
|
||||||
|
|
||||||
protected ThreadLocal<SessionContext> sessionContext = new ThreadLocal<>();
|
private ThreadLocal<SessionContext> sessionContext = new ThreadLocal<>();
|
||||||
protected Set<SessionPolicy> sessionPolicy = EnumSet.of(SessionPolicy.DEFAULT);
|
private Set<SessionPolicy> sessionPolicy = EnumSet.of(SessionPolicy.DEFAULT);
|
||||||
|
|
||||||
private static final Log LOGGER = LogFactory.getLog(SessionManager.class);
|
private static final Log LOGGER = LogFactory.getLog(SessionManager.class);
|
||||||
|
|
||||||
/** To get session persist policies */
|
|
||||||
public String getSessionPersistPolicies() {
|
|
||||||
String policyStr = null;
|
|
||||||
for (SessionPolicy policy : this.sessionPolicy) {
|
|
||||||
policyStr = (policyStr == null) ? policy.name() : policyStr.concat(",").concat(policy.name());
|
|
||||||
}
|
|
||||||
return policyStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** To set session persist policies */
|
|
||||||
public void setSessionPersistPolicies(String policyStr) {
|
|
||||||
Set<SessionPolicy> policySet = EnumSet.of(SessionPolicy.DEFAULT);
|
|
||||||
String[] policyArray = policyStr.split(",");
|
|
||||||
|
|
||||||
for (String policy : policyArray) {
|
|
||||||
policySet.add(SessionPolicy.fromName(policy));
|
|
||||||
}
|
|
||||||
this.sessionPolicy = policySet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getSaveOnChange() {
|
public boolean getSaveOnChange() {
|
||||||
return this.sessionPolicy.contains(SessionPolicy.SAVE_ON_CHANGE);
|
return this.sessionPolicy.contains(SessionPolicy.SAVE_ON_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getAlwaysSaveAfterRequest() {
|
|
||||||
return this.sessionPolicy.contains(SessionPolicy.ALWAYS_SAVE_AFTER_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public void addLifecycleListener(LifecycleListener listener) {
|
public void addLifecycleListener(LifecycleListener listener) {
|
||||||
|
@ -93,8 +67,8 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
Context context = getContextIns();
|
Context context = getContextIns();
|
||||||
for (Valve valve : context.getPipeline().getValves()) {
|
for (Valve valve : context.getPipeline().getValves()) {
|
||||||
if (valve instanceof SessionHandlerValve) {
|
if (valve instanceof SessionHandlerValve) {
|
||||||
this.handlerValve = (SessionHandlerValve) valve;
|
SessionHandlerValve handlerValve = (SessionHandlerValve) valve;
|
||||||
this.handlerValve.setSessionManager(this);
|
handlerValve.setSessionManager(this);
|
||||||
initializedValve = true;
|
initializedValve = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -103,9 +77,7 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
if (!initializedValve) {
|
if (!initializedValve) {
|
||||||
throw new LifecycleException("Session handling valve is not initialized..");
|
throw new LifecycleException("Session handling valve is not initialized..");
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
LOGGER.info("The sessions will expire after " + (getSessionTimeout(null)) + " seconds.");
|
LOGGER.info("The sessions will expire after " + (getSessionTimeout(null)) + " seconds.");
|
||||||
context.setDistributable(true);
|
context.setDistributable(true);
|
||||||
}
|
}
|
||||||
|
@ -166,41 +138,41 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public Session findSession(String sessionId) throws IOException {
|
public Session findSession(String sessionId) throws IOException {
|
||||||
Session session = null;
|
|
||||||
if (sessionId != null && this.sessionContext.get() != null && sessionId.equals(this.sessionContext.get().getId())) {
|
if (sessionId != null && this.sessionContext.get() != null && sessionId.equals(this.sessionContext.get().getId())) {
|
||||||
session = this.sessionContext.get().getSession();
|
return this.sessionContext.get().getSession();
|
||||||
} else {
|
|
||||||
byte[] data = this.dataCache.get(sessionId);
|
|
||||||
|
|
||||||
boolean isPersisted = false;
|
|
||||||
SessionMetadata metadata = null;
|
|
||||||
if (data == null) {
|
|
||||||
sessionId = null;
|
|
||||||
isPersisted = false;
|
|
||||||
} else {
|
|
||||||
if (Arrays.equals(SessionConstants.NULL_SESSION, data)) {
|
|
||||||
throw new IOException("NULL session data");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
metadata = new SessionMetadata();
|
|
||||||
Session newSession = createEmptySession();
|
|
||||||
this.serializer.deserializeSessionData(data, newSession, metadata);
|
|
||||||
|
|
||||||
newSession.setId(sessionId);
|
|
||||||
newSession.access();
|
|
||||||
newSession.setNew(false);
|
|
||||||
newSession.setValid(true);
|
|
||||||
newSession.resetDirtyTracking();
|
|
||||||
newSession.setMaxInactiveInterval(getSessionTimeout(newSession));
|
|
||||||
|
|
||||||
session = newSession;
|
|
||||||
isPersisted = true;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LOGGER.error("Error occurred while de-serializing the session object..", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setValues(sessionId, session, isPersisted, metadata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Session session = null;
|
||||||
|
boolean isPersisted = false;
|
||||||
|
SessionMetadata metadata = null;
|
||||||
|
|
||||||
|
byte[] data = this.dataCache.get(sessionId);
|
||||||
|
if (data == null) {
|
||||||
|
sessionId = null;
|
||||||
|
isPersisted = false;
|
||||||
|
} else {
|
||||||
|
if (Arrays.equals(SessionConstants.NULL_SESSION, data)) {
|
||||||
|
throw new IOException("NULL session data");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
metadata = new SessionMetadata();
|
||||||
|
Session newSession = createEmptySession();
|
||||||
|
this.serializer.deserializeSessionData(data, newSession, metadata);
|
||||||
|
|
||||||
|
newSession.setId(sessionId);
|
||||||
|
newSession.access();
|
||||||
|
newSession.setNew(false);
|
||||||
|
newSession.setValid(true);
|
||||||
|
newSession.resetDirtyTracking();
|
||||||
|
newSession.setMaxInactiveInterval(getSessionTimeout(newSession));
|
||||||
|
|
||||||
|
session = newSession;
|
||||||
|
isPersisted = true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOGGER.error("Error occurred while de-serializing the session object..", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setValues(sessionId, session, isPersisted, metadata);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,20 +190,20 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public void load() throws ClassNotFoundException, IOException {
|
public void load() {
|
||||||
// Auto-generated method stub
|
// Auto-generated method stub
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public void unload() throws IOException {
|
public void unload() {
|
||||||
// Auto-generated method stub
|
// Auto-generated method stub
|
||||||
}
|
}
|
||||||
|
|
||||||
/** To initialize the session manager. */
|
/** To initialize the session manager. */
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
try {
|
try {
|
||||||
this.dataCache = new RedisCache();
|
this.dataCache = new DataCacheFactory(getSessionTimeout(null)).getDataCache();
|
||||||
this.serializer = new SerializationUtil();
|
this.serializer = new SerializationUtil();
|
||||||
Context context = getContextIns();
|
Context context = getContextIns();
|
||||||
ClassLoader loader = (context != null && context.getLoader() != null) ? context.getLoader().getClassLoader() : null;
|
ClassLoader loader = (context != null && context.getLoader() != null) ? context.getLoader().getClassLoader() : null;
|
||||||
|
@ -249,7 +221,7 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
Session newSession = (Session) session;
|
Session newSession = (Session) session;
|
||||||
byte[] hash = (this.sessionContext.get() != null && this.sessionContext.get().getMetadata() != null)
|
byte[] hash = (this.sessionContext.get() != null && this.sessionContext.get().getMetadata() != null)
|
||||||
? this.sessionContext.get().getMetadata().getAttributesHash() : null;
|
? this.sessionContext.get().getMetadata().getAttributesHash() : null;
|
||||||
byte[] currentHash = serializer.getSessionAttributesHashCode(newSession);
|
byte[] currentHash = this.serializer.getSessionAttributesHashCode(newSession);
|
||||||
|
|
||||||
if (forceSave
|
if (forceSave
|
||||||
|| newSession.isDirty()
|
|| newSession.isDirty()
|
||||||
|
@ -259,7 +231,7 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
SessionMetadata metadata = new SessionMetadata();
|
SessionMetadata metadata = new SessionMetadata();
|
||||||
metadata.setAttributesHash(currentHash);
|
metadata.setAttributesHash(currentHash);
|
||||||
|
|
||||||
this.dataCache.set(newSession.getId(), serializer.serializeSessionData(newSession, metadata));
|
this.dataCache.set(newSession.getId(), this.serializer.serializeSessionData(newSession, metadata));
|
||||||
newSession.resetDirtyTracking();
|
newSession.resetDirtyTracking();
|
||||||
setValues(true, metadata);
|
setValues(true, metadata);
|
||||||
}
|
}
|
||||||
|
@ -274,13 +246,13 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** To process post request process. */
|
/** To process post request process. */
|
||||||
public void afterRequest(Request request) {
|
void afterRequest() {
|
||||||
Session session = null;
|
Session session = null;
|
||||||
try {
|
try {
|
||||||
session = (this.sessionContext.get() != null) ? this.sessionContext.get().getSession() : null;
|
session = (this.sessionContext.get() != null) ? this.sessionContext.get().getSession() : null;
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
if (session.isValid()) {
|
if (session.isValid()) {
|
||||||
save(session, getAlwaysSaveAfterRequest());
|
save(session, this.sessionPolicy.contains(SessionPolicy.ALWAYS_SAVE_AFTER_REQUEST));
|
||||||
} else {
|
} else {
|
||||||
remove(session);
|
remove(session);
|
||||||
}
|
}
|
||||||
|
@ -340,5 +312,4 @@ public class SessionManager extends ManagerBase implements Lifecycle {
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Error occurred while creating container instance");
|
throw new RuntimeException("Error occurred while creating container instance");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue