diff --git a/.gitignore b/.gitignore index 982a41f6..449207cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,13 @@ .gradle/* build/* +target/* example-app/build/* example-app/.gradle/* .DS_Store .rspec *.iml .idea/* +/target/ +.project +.classpath +/.settings diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 77759ee0..00000000 --- a/Gemfile +++ /dev/null @@ -1,5 +0,0 @@ -source "https://rubygems.org" - -gem 'redis' -gem 'rspec' -gem 'httparty' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 14a602d5..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,30 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - diff-lcs (1.2.5) - httparty (0.12.0) - json (~> 1.8) - multi_xml (>= 0.5.2) - json (1.8.1) - multi_xml (0.5.5) - redis (3.1.0) - rspec (3.1.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-core (3.1.4) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.1) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) - rspec-mocks (3.1.1) - rspec-support (~> 3.1.0) - rspec-support (3.1.0) - -PLATFORMS - ruby - -DEPENDENCIES - httparty - redis - rspec diff --git a/README.markdown b/README.md similarity index 100% rename from README.markdown rename to README.md diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 2bd0db6a..00000000 --- a/build.gradle +++ /dev/null @@ -1,99 +0,0 @@ -apply plugin: 'java' -apply plugin: 'maven' -apply plugin: 'signing' - -group = 'com.orangefunction' -version = '2.0.0' - -repositories { - mavenCentral() -} - -compileJava { - sourceCompatibility = 1.7 - targetCompatibility = 1.7 -} - -dependencies { - compile group: 'org.apache.tomcat', name: 'tomcat-catalina', version: '7.0.27' - compile group: 'redis.clients', name: 'jedis', version: '2.5.2' - compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.2' - //compile group: 'commons-codec', name: 'commons-codec', version: '1.9' - - testCompile group: 'junit', name: 'junit', version: '4.+' - testCompile 'org.hamcrest:hamcrest-core:1.3' - testCompile 'org.hamcrest:hamcrest-library:1.3' - testCompile 'org.mockito:mockito-all:1.9.5' - testCompile group: 'org.apache.tomcat', name: 'tomcat-coyote', version: '7.0.27' -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from 'build/docs/javadoc' -} - -task sourcesJar(type: Jar) { - from sourceSets.main.allSource - classifier = 'sources' -} - -artifacts { - archives jar - - archives javadocJar - archives sourcesJar -} - -signing { - sign configurations.archives -} - -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: sonatypeUsername, password: sonatypePassword) - } - //repository(url: "https://oss.sonatype.org/content/repositories/snapshots") { - // authentication(userName: sonatypeUsername, password: sonatypePassword) - //} - - pom.project { - name 'tomcat-redis-session-manager' - packaging 'jar' - description 'Tomcat Redis Session Manager is a Tomcat extension to store sessions in Redis' - url 'https://github.com/jcoleman/tomcat-redis-session-manager' - - issueManagement { - url 'https://github.com:jcoleman/tomcat-redis-session-manager/issues' - system 'GitHub Issues' - } - - scm { - url 'https://github.com:jcoleman/tomcat-redis-session-manager' - connection 'scm:git:git://github.com/jcoleman/tomcat-redis-session-manager.git' - developerConnection 'scm:git:git@github.com:jcoleman/tomcat-redis-session-manager.git' - } - - licenses { - license { - name 'MIT' - url 'http://opensource.org/licenses/MIT' - distribution 'repo' - } - } - - developers { - developer { - id 'jcoleman' - name 'James Coleman' - email 'jtc331@gmail.com' - url 'https://github.com/jcoleman' - } - } - } - } - } -} diff --git a/example-app/build.gradle b/example-app/build.gradle deleted file mode 100644 index 6f6690cb..00000000 --- a/example-app/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -apply plugin: 'java' -apply plugin: 'war' - -version = '0.1' - -repositories { - mavenCentral() -} - -compileJava { - sourceCompatibility = 1.7 - targetCompatibility = 1.7 -} - -dependencies { - providedCompile group: 'org.apache.tomcat', name: 'tomcat-catalina', version: '7.0.27' - compile group: 'redis.clients', name: 'jedis', version: '2.5.2' - compile group: 'com.sparkjava', name: 'spark-core', version: '1.1.1' - compile group: 'com.google.code.gson', name: 'gson', version: '2.3' - compile group: 'org.slf4j', name: 'slf4j-simple',version: '1.7.5' - providedCompile project(":tomcat-redis-session-manager") -} - -war { - //webAppDirName = 'source/main/' - - //from 'src/rootContent' // adds a file-set to the root of the archive - //webInf { from 'src/additionalWebInf' } // adds a file-set to the WEB-INF dir. - //classpath fileTree('additionalLibs') // adds a file-set to the WEB-INF/lib dir. - //classpath configurations.moreLibs // adds a configuration to the WEB-INF/lib dir. -} \ No newline at end of file diff --git a/example-app/settings.gradle b/example-app/settings.gradle deleted file mode 100644 index f48382b1..00000000 --- a/example-app/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ":tomcat-redis-session-manager" -project(":tomcat-redis-session-manager").projectDir = new File(rootDir, "../") diff --git a/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/JsonTransformerRoute.java b/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/JsonTransformerRoute.java deleted file mode 100644 index 46d95fb5..00000000 --- a/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/JsonTransformerRoute.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.orangefunction.tomcatredissessionmanager.exampleapp; - -import com.google.gson.Gson; -import com.orangefunction.tomcat.redissessions.RedisSession; -import java.util.HashMap; -import java.util.Collections; -import spark.ResponseTransformerRoute; -import spark.Session; -import javax.servlet.http.HttpSession; - -public abstract class JsonTransformerRoute extends ResponseTransformerRoute { - - private Gson gson = new Gson(); - - protected JsonTransformerRoute(String path) { - super(path); - } - - protected JsonTransformerRoute(String path, String acceptType) { - super(path, acceptType); - } - - @Override - public String render(Object jsonObject) { - return gson.toJson(jsonObject); - } - -} \ No newline at end of file diff --git a/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/SessionJsonTransformerRoute.java b/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/SessionJsonTransformerRoute.java deleted file mode 100644 index 61bf1f18..00000000 --- a/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/SessionJsonTransformerRoute.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.orangefunction.tomcatredissessionmanager.exampleapp; - -import com.google.gson.Gson; -import com.orangefunction.tomcat.redissessions.RedisSession; -import java.util.HashMap; -import java.util.Map; -import java.util.Collections; -import spark.ResponseTransformerRoute; -import spark.Session; -import javax.servlet.http.HttpSession; - -public abstract class SessionJsonTransformerRoute extends ResponseTransformerRoute { - - private Gson gson = new Gson(); - - protected SessionJsonTransformerRoute(String path) { - super(path); - } - - protected SessionJsonTransformerRoute(String path, String acceptType) { - super(path, acceptType); - } - - @Override - public String render(Object object) { - if (object instanceof Object[]) { - Object[] tuple = (Object[])object; - Session sparkSession = (Session)tuple[0]; - HttpSession session = (HttpSession)(sparkSession).raw(); - HashMap map = new HashMap(); - map.putAll((Map)tuple[1]); - map.put("sessionId", session.getId()); - return gson.toJson(map); - } else if (object instanceof Session) { - Session sparkSession = (Session)object; - HashMap sessionMap = new HashMap(); - if (null != sparkSession) { - HttpSession session = (HttpSession)(sparkSession).raw(); - sessionMap.put("sessionId", session.getId()); - HashMap attributesMap = new HashMap(); - for (String key : Collections.list(session.getAttributeNames())) { - attributesMap.put(key, session.getAttribute(key)); - } - sessionMap.put("attributes", attributesMap); - } - return gson.toJson(sessionMap); - } else { - return "{}"; - } - } - -} \ No newline at end of file diff --git a/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/WebApp.java b/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/WebApp.java deleted file mode 100644 index e2fe6a6f..00000000 --- a/example-app/src/main/java/com/orangefunction/tomcatredissessionmanager/exampleapp/WebApp.java +++ /dev/null @@ -1,317 +0,0 @@ -package com.orangefunction.tomcatredissessionmanager.exampleapp; - -import java.util.Map; -import java.util.Map.Entry; -import java.util.HashMap; -import java.util.Set; -import static spark.Spark.*; -import spark.*; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.Protocol; -import com.orangefunction.tomcat.redissessions.*; -import org.apache.catalina.session.StandardSession; -import org.apache.catalina.session.StandardSessionFacade; -import org.apache.catalina.core.ApplicationContextFacade; -import org.apache.catalina.core.ApplicationContext; -import org.apache.catalina.core.StandardContext; -import java.lang.reflect.Field; -import javax.servlet.*; - -import org.apache.juli.logging.Log; -import org.apache.juli.logging.LogFactory; - -public class WebApp implements spark.servlet.SparkApplication { - - private final Log log = LogFactory.getLog(WebApp.class); - - protected String redisHost = "localhost"; - protected int redisPort = 6379; - protected int redisDatabase = 0; - protected String redisPassword = null; - protected int redisTimeout = Protocol.DEFAULT_TIMEOUT; - protected JedisPool redisConnectionPool; - - private void initializeJedisConnectionPool() { - try { - redisConnectionPool = new JedisPool(new JedisPoolConfig(), redisHost, redisPort, redisTimeout, redisPassword); - } catch (Exception e) { - e.printStackTrace(); - } - } - - protected Jedis acquireConnection() { - if (null == redisConnectionPool) { - initializeJedisConnectionPool(); - } - Jedis jedis = redisConnectionPool.getResource(); - - if (redisDatabase != 0) { - jedis.select(redisDatabase); - } - - return jedis; - } - - protected void returnConnection(Jedis jedis, Boolean error) { - if (error) { - redisConnectionPool.returnBrokenResource(jedis); - } else { - redisConnectionPool.returnResource(jedis); - } - } - - protected void returnConnection(Jedis jedis) { - returnConnection(jedis, false); - } - - protected RedisSessionManager getRedisSessionManager(Request request) { - RedisSessionManager sessionManager = null; - ApplicationContextFacade appContextFacadeObj = (ApplicationContextFacade)request.session().raw().getServletContext(); - try { - Field applicationContextField = appContextFacadeObj.getClass().getDeclaredField("context"); - applicationContextField.setAccessible(true); - ApplicationContext appContextObj = (ApplicationContext)applicationContextField.get(appContextFacadeObj); - Field standardContextField = appContextObj.getClass().getDeclaredField("context"); - standardContextField.setAccessible(true); - StandardContext standardContextObj = (StandardContext)standardContextField.get(appContextObj); - sessionManager = (RedisSessionManager)standardContextObj.getManager(); - } catch (Exception e) { } - return sessionManager; - } - - protected void updateSessionFromQueryParamsMap(Session session, QueryParamsMap queryParamsMap) { - for (Entry kv : queryParamsMap.toMap().entrySet()) { - String key = kv.getKey(); - QueryParamsMap subParamsMap = queryParamsMap.get(kv.getKey()); - if (subParamsMap.hasKeys()) { - Object currentValue = session.attribute(key); - Map subMap; - if (currentValue instanceof Map) { - subMap = (Map)currentValue; - } else { - subMap = new HashMap(); - session.attribute(key, subMap); - } - updateMapFromQueryParamsMap(subMap, subParamsMap); - } else if (subParamsMap.hasValue()) { - Object value = subParamsMap.value(); - //log.info("found key " + key + " and value " + (null == value ? "`null`" : value.toString())); - session.attribute(key, value); - } - } - } - - protected void updateMapFromQueryParamsMap(Map map, QueryParamsMap queryParamsMap) { - for (Entry kv : queryParamsMap.toMap().entrySet()) { - String key = kv.getKey(); - QueryParamsMap subParamsMap = queryParamsMap.get(kv.getKey()); - if (subParamsMap.hasKeys()) { - Object currentValue = map.get(key); - Map subMap; - if (currentValue instanceof Map) { - subMap = (Map)currentValue; - } else { - subMap = new HashMap(); - map.put(key, subMap); - } - updateMapFromQueryParamsMap(subMap, subParamsMap); - } else if (subParamsMap.hasValue()) { - Object value = subParamsMap.value(); - //log.info("found key " + key + " and value " + (null == value ? "`null`" : value.toString())); - map.put(key, value); - } - } - } - - public void init() { - - // /session - - get(new SessionJsonTransformerRoute("/session", "application/json") { - @Override - public Object handle(Request request, Response response) { - return request.session(false); - } - }); - - - - put(new SessionJsonTransformerRoute("/session", "application/json") { - @Override - public Object handle(Request request, Response response) { - Session session = request.session(); - QueryParamsMap queryMap = request.queryMap(); - updateSessionFromQueryParamsMap(session, queryMap); - return session; - } - }); - - post(new SessionJsonTransformerRoute("/session", "application/json") { - @Override - public Object handle(Request request, Response response) { - Session session = request.session(); - QueryParamsMap queryMap = request.queryMap(); - updateSessionFromQueryParamsMap(session, queryMap); - return session; - } - }); - - delete(new SessionJsonTransformerRoute("/session", "application/json") { - @Override - public Object handle(Request request, Response response) { - request.session().raw().invalidate(); - return null; - } - }); - - - // /session/attributes - - get(new SessionJsonTransformerRoute("/session/attributes", "application/json") { - @Override - public Object handle(Request request, Response response) { - HashMap map = new HashMap(); - map.put("keys", request.session().attributes()); - return new Object[]{request.session(), map}; - } - }); - - get(new SessionJsonTransformerRoute("/session/attributes/:key", "application/json") { - @Override - public Object handle(Request request, Response response) { - String key = request.params(":key"); - HashMap map = new HashMap(); - map.put("key", key); - map.put("value", request.session().attribute(key)); - return new Object[]{request.session(), map}; - } - }); - - post(new SessionJsonTransformerRoute("/session/attributes/:key", "application/json") { - @Override - public Object handle(Request request, Response response) { - String key = request.params(":key"); - String oldValue = request.session().attribute(key); - request.session().attribute(key, request.queryParams("value")); - HashMap map = new HashMap(); - map.put("key", key); - map.put("value", request.session().attribute(key)); - map.put("oldValue", oldValue); - if (null != request.queryParams("sleep")) { - try { - java.lang.Thread.sleep(Integer.parseInt(request.queryParams("sleep"))); - } catch (InterruptedException e) {} - } - return new Object[]{request.session(), map}; - } - }); - - delete(new SessionJsonTransformerRoute("/session/attributes/:key", "application/json") { - @Override - public Object handle(Request request, Response response) { - String key = request.params(":key"); - String oldValue = request.session().attribute(key); - request.session().raw().removeAttribute(key); - HashMap map = new HashMap(); - map.put("key", key); - map.put("value", request.session().attribute(key)); - map.put("oldValue", oldValue); - return new Object[]{request.session(), map}; - } - }); - - - // /sessions - - get(new JsonTransformerRoute("/sessions", "application/json") { - @Override - public Object handle(Request request, Response response) { - Jedis jedis = null; - Boolean error = true; - try { - jedis = acquireConnection(); - Set keySet = jedis.keys("*"); - error = false; - return keySet.toArray(new String[keySet.size()]); - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } - } - } - }); - - delete(new JsonTransformerRoute("/sessions", "application/json") { - @Override - public Object handle(Request request, Response response) { - Jedis jedis = null; - Boolean error = true; - try { - jedis = acquireConnection(); - jedis.flushDB(); - Set keySet = jedis.keys("*"); - error = false; - return keySet.toArray(new String[keySet.size()]); - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } - } - } - }); - - - // /settings - - get(new SessionJsonTransformerRoute("/settings/:key", "application/json") { - @Override - public Object handle(Request request, Response response) { - String key = request.params(":key"); - HashMap map = new HashMap(); - map.put("key", key); - - RedisSessionManager manager = getRedisSessionManager(request); - if (null != manager) { - if (key.equals("sessionPersistPolicies")) { - map.put("value", manager.getSessionPersistPolicies()); - } else if (key.equals("maxInactiveInterval")) { - map.put("value", new Integer(manager.getMaxInactiveInterval())); - } - } else { - map.put("error", new Boolean(true)); - } - - return new Object[]{request.session(), map}; - } - }); - - post(new SessionJsonTransformerRoute("/settings/:key", "application/json") { - @Override - public Object handle(Request request, Response response) { - String key = request.params(":key"); - String value = request.queryParams("value"); - HashMap map = new HashMap(); - map.put("key", key); - - RedisSessionManager manager = getRedisSessionManager(request); - if (null != manager) { - if (key.equals("sessionPersistPolicies")) { - manager.setSessionPersistPolicies(value); - map.put("value", manager.getSessionPersistPolicies()); - } else if (key.equals("maxInactiveInterval")) { - manager.setMaxInactiveInterval(Integer.parseInt(value)); - map.put("value", new Integer(manager.getMaxInactiveInterval())); - } - } else { - map.put("error", new Boolean(true)); - } - - return new Object[]{request.session(), map}; - } - }); - - } - -} diff --git a/example-app/src/main/webapp/META-INF/context.xml b/example-app/src/main/webapp/META-INF/context.xml deleted file mode 100644 index ad32563d..00000000 --- a/example-app/src/main/webapp/META-INF/context.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/example-app/src/main/webapp/WEB-INF/web.xml b/example-app/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index dbe44d69..00000000 --- a/example-app/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - Tomcat Redis Session Manager Example App - - SparkFilter - spark.servlet.SparkFilter - - applicationClass - com.orangefunction.tomcatredissessionmanager.exampleapp.WebApp - - - - - SparkFilter - /* - - - - diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..44f4375e --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + com.orangefunction + tomcat-session-redis + 8.5 + jar + + tomcat-session-redis + http://maven.apache.org + + + + UTF-8 + UTF-8 + + + + + + junit + junit + 4.11 + test + + + org.apache.tomcat + tomcat-catalina + 8.5.3 + + + org.apache.tomcat + tomcat-util + 8.5.3 + + + redis.clients + jedis + LATEST + + + org.apache.commons + commons-pool2 + 2.2 + + + commons-codec + commons-codec + 1.9 + + + + + + + src/main/resources + true + + + + + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + utf-8 + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + process-resources + + copy-dependencies + + + compile + ${project.build.directory}/lib + + + + + + + diff --git a/spec/requests/always_save_after_request_spec.rb b/spec/requests/always_save_after_request_spec.rb deleted file mode 100644 index 94e2e59f..00000000 --- a/spec/requests/always_save_after_request_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'spec_helper' - -describe "ALWAYS_SAVE_AFTER_REQUEST" do - - before :each do - get("#{SETTINGS_PATH}/sessionPersistPolicies") - @oldSessionPersistPoliciesValue = json['value'] - enums = @oldSessionPersistPoliciesValue.split(',') - enums << 'ALWAYS_SAVE_AFTER_REQUEST' - post("#{SETTINGS_PATH}/sessionPersistPolicies", body: {value: enums.join(',')}) - end - - after :each do - post("#{SETTINGS_PATH}/sessionPersistPolicies", body: {value: @oldSessionPersistPoliciesValue}) - end - - it 'should optionally support persisting the session after every request regardless of changed status' do - post(SESSION_PATH, body: {param2: '5'}) - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '5' - - # This is not a perfect guarantee, but in general we're assuming - # that the requests will happen in the following order: - # - Post(value=5) starts - # - Post(value=6) starts - # - Post(value=6) finishes - # - Get() returns 6 - # - Post(value=5) finishes - # - Get() returns 5 (because the change value=5 saved on request finish even though it wasn't a change) - long_request = Thread.new do - post("#{SESSION_ATTRIBUTES_PATH}/param2", body: {value: '5', sleep: 2000}) - end - - sleep 0.5 - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '5' - - post("#{SESSION_ATTRIBUTES_PATH}/param2", body: {value: '6'}) - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '6' - - long_request.join - - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '5' - end -end diff --git a/spec/requests/save_on_change_spec.rb b/spec/requests/save_on_change_spec.rb deleted file mode 100644 index b0c0db05..00000000 --- a/spec/requests/save_on_change_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'spec_helper' - -describe "SAVE_ON_CHANGE" do - - before :each do - get("#{SETTINGS_PATH}/sessionPersistPolicies") - @oldSessionPersistPoliciesValue = json['value'] - enums = @oldSessionPersistPoliciesValue.split(',') - enums << 'SAVE_ON_CHANGE' - post("#{SETTINGS_PATH}/sessionPersistPolicies", body: {value: enums.join(',')}) - end - - after :each do - post("#{SETTINGS_PATH}/sessionPersistPolicies", body: {value: @oldSessionPersistPoliciesValue}) - end - - it 'should support persisting the session on change to minimize race conditions on simultaneous updates' do - post(SESSION_PATH, body: {param2: '5'}) - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '5' - - # This is not a perfect guarantee, but in general we're assuming - # that the requests will happen in the following order: - # - Post(value=5) starts - # - Post(value=6) starts - # - Post(value=6) finishes - # - Get() returns 6 - # - Post(value=5) finishes - # - Get() returns 6 (because the change value=5 saved immediately rather than on request finish) - long_request = Thread.new do - post("#{SESSION_ATTRIBUTES_PATH}/param2", body: {value: '5', sleep: 2000}) - end - - sleep 0.5 - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '5' - - post("#{SESSION_ATTRIBUTES_PATH}/param2", body: {value: '6'}) - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '6' - - long_request.join - - get("#{SESSION_ATTRIBUTES_PATH}/param2") - json['value'].should == '6' - end -end diff --git a/spec/requests/session_creation_spec.rb b/spec/requests/session_creation_spec.rb deleted file mode 100644 index 62753abf..00000000 --- a/spec/requests/session_creation_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe 'session creation' do - - it 'should begin without a session' do - get(SESSION_PATH) - json.should_not have_key('sessionId') - end - - it 'should generate a session ID' do - post(SESSION_PATH) - json.should have_key('sessionId') - end - - it 'should not create a session when requesting session creation with existing session ID' do - pending - end - - it 'should detect a session ID collision and generate a new session ID' do - pending - end - - it 'should detect and report race conditions when creating new sessions' do - pending - end -end diff --git a/spec/requests/session_expiration_spec.rb b/spec/requests/session_expiration_spec.rb deleted file mode 100644 index e16b0c0d..00000000 --- a/spec/requests/session_expiration_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'spec_helper' - -describe 'session expiration' do - - before :each do - get("#{SETTINGS_PATH}/maxInactiveInterval") - @oldMaxInactiveIntervalValue = json['value'] - post("#{SETTINGS_PATH}/maxInactiveInterval", body: {value: '1'}) - end - - after :each do - post("#{SETTINGS_PATH}/maxInactiveInterval", body: {value: @oldMaxInactiveIntervalValue}) - end - - it 'should no longer contain a session after the expiration timeout has passed' do - post(SESSION_PATH) - created_session_id = json['sessionId'] - get(SESSION_PATH) - json['sessionId'].should == created_session_id - sleep 1.0 - get(SESSION_PATH) - json['sessionId'].should be_nil - end -end diff --git a/spec/requests/session_updating_spec.rb b/spec/requests/session_updating_spec.rb deleted file mode 100644 index 8e5d81f9..00000000 --- a/spec/requests/session_updating_spec.rb +++ /dev/null @@ -1,114 +0,0 @@ -require 'spec_helper' - -describe 'session updating' do - it 'should support setting a value in the session' do - post(SESSION_PATH, body: {param1: '5'}) - json['attributes'].should have_key('param1') - json['attributes']['param1'].should == '5' - end - - it 'should support updating a value in the session' do - post(SESSION_PATH, body: {param1: '5'}) - json['attributes'].should have_key('param1') - json['attributes']['param1'].should == '5' - - put(SESSION_PATH, query: {param1: '6'}) - json['attributes']['param1'].should == '6' - end - - it 'should support setting a complex values in the session' do - post(SESSION_PATH, body: {param1: {subparam: '5'}}) - json['attributes']['param1'].should have_key('subparam') - json['attributes']['param1']['subparam'].should == '5' - end - - it 'should persist session attributes between requests' do - post(SESSION_PATH, body: {param1: '5'}) - get(SESSION_PATH) - json['attributes']['param1'].should == '5' - end - - it 'should persist updated session attributes between requests' do - post(SESSION_PATH, body: {param1: '5'}) - put(SESSION_PATH, query: {param1: '6'}) - get(SESSION_PATH) - json['attributes']['param1'].should == '6' - end - - it 'should support removing a value in the session' do - post("#{SESSION_ATTRIBUTES_PATH}/param1", body: {value: '5'}) - get(SESSION_ATTRIBUTES_PATH) - json['keys'].should include('param1') - - delete("#{SESSION_ATTRIBUTES_PATH}/param1") - get(SESSION_ATTRIBUTES_PATH) - json['keys'].should_not include('param1') - end - - it 'should only update if the session changes' do - post(SESSION_PATH, body: {param1: '5'}) - - # This is not a perfect guarantee, but in general we're assuming - # that the requests will happen in the following order: - # - Post(value=5) starts - # - Post(value=6) starts - # - Post(value=6) finishes - # - Get() returns 6 - # - Post(value=5) finishes - # Note: this would represent a change from the current persisted value - # but it does not represent a change from when this request's - # copy of the session was loaded, so it shouldn't be persisted. - # - Get() returns 6 - last_request_to_finish = Thread.new do - post("#{SESSION_ATTRIBUTES_PATH}/param1", body: {value: '5', sleep: 2000}) - end - sleep 1 - post("#{SESSION_ATTRIBUTES_PATH}/param1", body: {value: '6'}) - # Verify our assumption that this request loaded it's session - # before the request Post(value=7) finished. - json['oldValue'].should == '5' - get("#{SESSION_ATTRIBUTES_PATH}/param1") - json['value'].should == '6' - - last_request_to_finish.join - - get("#{SESSION_ATTRIBUTES_PATH}/param1") - json['value'].should == '6' - end - - it 'should detect nested changes and persist them' do - post(SESSION_PATH, body: {param1: {subparam: '5'}}) - json['attributes']['param1']['subparam'].should == '5' - post(SESSION_PATH, body: {param1: {subparam: '6'}}) - get(SESSION_PATH) - json['attributes']['param1']['subparam'].should == '6' - end - - it 'should default to last-write-wins behavior for simultaneous updates' do - post(SESSION_PATH, body: {param1: '5'}) - - # This is not a perfect guarantee, but in general we're assuming - # that the requests will happen in the following order: - # - Post(value=7) starts - # - Post(value=6) starts - # - Post(value=6) finishes - # - Get() returns 6 - # - Post(value=7) finishes - # - Get() returns 7 - winner = Thread.new do - post("#{SESSION_ATTRIBUTES_PATH}/param1", body: {value: '7', sleep: 2000}) - end - sleep 1 - post("#{SESSION_ATTRIBUTES_PATH}/param1", body: {value: '6'}) - # Verify our assumption that this request loaded it's session - # before the request Post(value=7) finished. - json['oldValue'].should == '5' - get("#{SESSION_ATTRIBUTES_PATH}/param1") - json['value'].should == '6' - - winner.join - - get("#{SESSION_ATTRIBUTES_PATH}/param1") - json['value'].should == '7' - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index a1d3a831..00000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,73 +0,0 @@ -require File.expand_path('../support/requests_helper', __FILE__) - -SESSION_PATH = '/session' -SESSIONS_PATH = '/sessions' -SESSION_ATTRIBUTES_PATH = '/session/attributes' -SETTINGS_PATH = '/settings' - -# This file was generated by the `rspec --init` command. Conventionally, all -# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. -# Require this file using `require "spec_helper"` to ensure that it is only -# loaded once. -# -# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration -RSpec.configure do |config| - config.treat_symbols_as_metadata_keys_with_true_values = true - config.run_all_when_everything_filtered = true - config.filter_run :focus - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = 'random' - - config.include RequestsHelper - - should_build_and_install_on_vagrant = true - has_built_and_installed_on_vagrant = false - - config.before :all do - root_project_path = File.expand_path('../../', __FILE__) - vagrant_path = File.join(root_project_path, 'vagrant', 'tomcat-redis-example') - example_app_path = File.join(root_project_path, 'example-app') - #unless `cd #{vagrant_path} && vagrant status --machine-readable | awk -F, '$3 ~ /^state$/ { print $4}'`.strip == 'running' - # raise "Expected vagrant to be running." - #end - - if should_build_and_install_on_vagrant && !has_built_and_installed_on_vagrant - # build manager - build_manager_command = <<-eos - cd #{root_project_path} \ - && gradle clean \ - && gradle build - eos - `#{build_manager_command}` - - # build example app - build_example_app_command = <<-eos - cd #{example_app_path} \ - && gradle clean \ - && gradle war - eos - `#{build_example_app_command}` - - deploy_command = <<-eos - cd #{vagrant_path} \ - && vagrant ssh -c "\ - sudo service tomcat7 stop \ - && sudo mkdir -p /var/lib/tomcat7/lib \ - && sudo rm -rf /var/lib/tomcat7/lib/tomcat-redis-session-manager* \ - && sudo cp /opt/tomcat-redis-session-manager/build/libs/tomcat-redis-session-manager*.jar /var/lib/tomcat7/lib/ \ - && sudo rm -rf /var/lib/tomcat7/webapps/example* \ - && sudo cp /opt/tomcat-redis-session-manager/example-app/build/libs/example-app*.war /var/lib/tomcat7/webapps/example.war \ - && sudo rm -f /var/log/tomcat7/* \ - && sudo service tomcat7 start \ - " - eos - `#{deploy_command}` - - has_built_and_installed_on_vagrant = true - end - end -end diff --git a/spec/support/requests_helper.rb b/spec/support/requests_helper.rb deleted file mode 100644 index 6ffdeb26..00000000 --- a/spec/support/requests_helper.rb +++ /dev/null @@ -1,67 +0,0 @@ -require 'httparty' - -module RequestsHelper - - class ExampleAppClient - include ::HTTParty - base_uri 'http://172.28.128.3:8080/example' - end - - def client - @client ||= ExampleAppClient.new - end - - def get(path, options={}) - send_request(:get, path, options) - end - - def put(path, options={}) - send_request(:put, path, options) - end - - def post(path, options={}) - send_request(:post, path, options) - end - - def delete(path, options={}) - send_request(:delete, path, options) - end - - def send_request(method, path, options={}) - options ||= {} - headers = options[:headers] || {} - if cookie && !options.key('Cookie') - headers['Cookie'] = cookie - end - options = options.merge(headers: headers) - self.response = self.client.class.send(method, path, options) - end - - def request - response.request - end - - def response - @response - end - - def response=(r) - if r - if r.headers.key?('Set-Cookie') - @cookie = r.headers['Set-Cookie'] - end - else - @cookie = nil - end - @json = nil - @response = r - end - - def cookie - @cookie - end - - def json - @json ||= JSON.parse(response.body) - end -end diff --git a/src/main/java/com/orangefunction/tomcat/redissessions/JavaSerializer.java b/src/main/java/com/orangefunction/tomcat/redissessions/JavaSerializer.java index 4cfedff4..9c04f8e4 100644 --- a/src/main/java/com/orangefunction/tomcat/redissessions/JavaSerializer.java +++ b/src/main/java/com/orangefunction/tomcat/redissessions/JavaSerializer.java @@ -1,22 +1,24 @@ package com.orangefunction.tomcat.redissessions; -import org.apache.catalina.util.CustomObjectInputStream; - -import javax.servlet.http.HttpSession; - -import java.util.Enumeration; -import java.util.HashMap; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; +import java.util.HashMap; +import org.apache.catalina.util.CustomObjectInputStream; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; public class JavaSerializer implements Serializer { - private ClassLoader loader; - private final Log log = LogFactory.getLog(JavaSerializer.class); + private ClassLoader loader; @Override public void setClassLoader(ClassLoader loader) { @@ -24,17 +26,17 @@ public void setClassLoader(ClassLoader loader) { } public byte[] attributesHashFrom(RedisSession session) throws IOException { - HashMap attributes = new HashMap(); + HashMap attributes = new HashMap<>(); for (Enumeration enumerator = session.getAttributeNames(); enumerator.hasMoreElements();) { String key = enumerator.nextElement(); attributes.put(key, session.getAttribute(key)); } - byte[] serialized = null; + byte[] serialized; try ( - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(bos)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(bos)) ) { oos.writeUnshared(attributes); oos.flush(); @@ -47,16 +49,16 @@ public byte[] attributesHashFrom(RedisSession session) throws IOException { } catch (NoSuchAlgorithmException e) { log.error("Unable to get MessageDigest instance for MD5"); } - return digester.digest(serialized); + return digester != null ? digester.digest(serialized) : new byte[0]; } @Override public byte[] serializeFrom(RedisSession session, SessionSerializationMetadata metadata) throws IOException { - byte[] serialized = null; + byte[] serialized; try ( - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(bos)); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(bos)) ) { oos.writeObject(metadata); session.writeObjectData(oos); @@ -70,8 +72,8 @@ public byte[] serializeFrom(RedisSession session, SessionSerializationMetadata m @Override public void deserializeInto(byte[] data, RedisSession session, SessionSerializationMetadata metadata) throws IOException, ClassNotFoundException { try( - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(data)); - ObjectInputStream ois = new CustomObjectInputStream(bis, loader); + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(data)); + ObjectInputStream ois = new CustomObjectInputStream(bis, loader) ) { SessionSerializationMetadata serializedMetadata = (SessionSerializationMetadata)ois.readObject(); metadata.copyFieldsFrom(serializedMetadata); diff --git a/src/main/java/com/orangefunction/tomcat/redissessions/RedisSession.java b/src/main/java/com/orangefunction/tomcat/redissessions/RedisSession.java index 0fa742d8..3a03a5da 100644 --- a/src/main/java/com/orangefunction/tomcat/redissessions/RedisSession.java +++ b/src/main/java/com/orangefunction/tomcat/redissessions/RedisSession.java @@ -12,29 +12,26 @@ public class RedisSession extends StandardSession { + private static Boolean manualDirtyTrackingSupportEnabled = false; + private static String manualDirtyTrackingAttributeKey = "__changed__"; private final Log log = LogFactory.getLog(RedisSession.class); + private HashMap changedAttributes; + private Boolean dirty; - protected static Boolean manualDirtyTrackingSupportEnabled = false; + + public RedisSession(Manager manager) { + super(manager); + resetDirtyTracking(); + } public static void setManualDirtyTrackingSupportEnabled(Boolean enabled) { manualDirtyTrackingSupportEnabled = enabled; } - protected static String manualDirtyTrackingAttributeKey = "__changed__"; - public static void setManualDirtyTrackingAttributeKey(String key) { manualDirtyTrackingAttributeKey = key; } - - protected HashMap changedAttributes; - protected Boolean dirty; - - public RedisSession(Manager manager) { - super(manager); - resetDirtyTracking(); - } - public Boolean isDirty() { return dirty || !changedAttributes.isEmpty(); } diff --git a/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionHandlerValve.java b/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionHandlerValve.java index 13da6765..2bd00144 100644 --- a/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionHandlerValve.java +++ b/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionHandlerValve.java @@ -1,13 +1,12 @@ package com.orangefunction.tomcat.redissessions; -import org.apache.catalina.Session; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; +import java.io.IOException; import javax.servlet.ServletException; -import java.io.IOException; +import org.apache.catalina.connector.Request; +import org.apache.catalina.connector.Response; +import org.apache.catalina.valves.ValveBase; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; diff --git a/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionManager.java b/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionManager.java index 2b58a261..bdc96668 100644 --- a/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionManager.java +++ b/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionManager.java @@ -1,358 +1,327 @@ package com.orangefunction.tomcat.redissessions; -import org.apache.catalina.Lifecycle; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.util.LifecycleSupport; -import org.apache.catalina.LifecycleState; -import org.apache.catalina.Loader; -import org.apache.catalina.Valve; -import org.apache.catalina.Session; -import org.apache.catalina.session.ManagerBase; - -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.apache.commons.pool2.impl.BaseObjectPoolConfig; - -import redis.clients.util.Pool; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisSentinelPool; -import redis.clients.jedis.JedisPoolConfig; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.Protocol; - import java.io.IOException; import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Set; import java.util.EnumSet; +import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; +import java.util.Set; +import org.apache.catalina.*; +import org.apache.catalina.session.ManagerBase; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.JedisSentinelPool; +import redis.clients.jedis.Protocol; +import redis.clients.util.Pool; + public class RedisSessionManager extends ManagerBase implements Lifecycle { - enum SessionPersistPolicy { - DEFAULT, - SAVE_ON_CHANGE, - ALWAYS_SAVE_AFTER_REQUEST; + protected static String name = "RedisSessionManager"; + private final byte[] NULL_SESSION = "null".getBytes(); + + private final Log log = LogFactory.getLog(RedisSessionManager.class); + private final JedisPoolConfig connectionPoolConfig = new JedisPoolConfig(); + private final ThreadLocal currentSession = new ThreadLocal<>(); + private final ThreadLocal currentSessionSerializationMetadata = new ThreadLocal<>(); + private final ThreadLocal currentSessionId = new ThreadLocal<>(); + private final ThreadLocal currentSessionIsPersisted = new ThreadLocal<>(); + private String host = "localhost"; + private int port = 6379; + private int database = 0; + private String password = null; + private int timeout = Protocol.DEFAULT_TIMEOUT; + private String sentinelMaster = null; + private Set sentinelSet = null; + private Pool connectionPool; + private RedisSessionHandlerValve handlerValve; + private Serializer serializer; + private String serializationStrategyClass = "com.orangefunction.tomcat.redissessions.JavaSerializer"; + private EnumSet sessionPersistPoliciesSet = EnumSet.of(SessionPersistPolicy.DEFAULT); + + /** + * The lifecycle event support for this component. + */ + // protected LifecycleSupport lifecycle = new LifecycleSupport(this); + private String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + private int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + private int getDatabase() { + return database; + } + + public void setDatabase(int database) { + this.database = database; + } + + private int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + private String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setSerializationStrategyClass(String strategy) { + this.serializationStrategyClass = strategy; + } + + public String getSessionPersistPolicies() { + StringBuilder policies = new StringBuilder(); + for (Iterator iter = this.sessionPersistPoliciesSet.iterator(); iter.hasNext(); ) { + SessionPersistPolicy policy = iter.next(); + policies.append(policy.name()); + if (iter.hasNext()) { + policies.append(","); + } + } + return policies.toString(); + } - static SessionPersistPolicy fromName(String name) { - for (SessionPersistPolicy policy : SessionPersistPolicy.values()) { - if (policy.name().equalsIgnoreCase(name)) { - return policy; + public void setSessionPersistPolicies(String sessionPersistPolicies) { + String[] policyArray = sessionPersistPolicies.split(","); + EnumSet policySet = EnumSet.of(SessionPersistPolicy.DEFAULT); + for (String policyName : policyArray) { + SessionPersistPolicy policy = SessionPersistPolicy.fromName(policyName); + policySet.add(policy); } - } - throw new IllegalArgumentException("Invalid session persist policy [" + name + "]. Must be one of " + Arrays.asList(SessionPersistPolicy.values())+ "."); + this.sessionPersistPoliciesSet = policySet; } - } - protected byte[] NULL_SESSION = "null".getBytes(); + public boolean getSaveOnChange() { + return this.sessionPersistPoliciesSet.contains(SessionPersistPolicy.SAVE_ON_CHANGE); + } - private final Log log = LogFactory.getLog(RedisSessionManager.class); + private boolean getAlwaysSaveAfterRequest() { + return this.sessionPersistPoliciesSet.contains(SessionPersistPolicy.ALWAYS_SAVE_AFTER_REQUEST); + } - protected String host = "localhost"; - protected int port = 6379; - protected int database = 0; - protected String password = null; - protected int timeout = Protocol.DEFAULT_TIMEOUT; - protected String sentinelMaster = null; - Set sentinelSet = null; - - protected Pool connectionPool; - protected JedisPoolConfig connectionPoolConfig = new JedisPoolConfig(); - - protected RedisSessionHandlerValve handlerValve; - protected ThreadLocal currentSession = new ThreadLocal<>(); - protected ThreadLocal currentSessionSerializationMetadata = new ThreadLocal<>(); - protected ThreadLocal currentSessionId = new ThreadLocal<>(); - protected ThreadLocal currentSessionIsPersisted = new ThreadLocal<>(); - protected Serializer serializer; + public String getSentinels() { + StringBuilder sentinels = new StringBuilder(); + for (Iterator iter = this.sentinelSet.iterator(); iter.hasNext(); ) { + sentinels.append(iter.next()); + if (iter.hasNext()) { + sentinels.append(","); + } + } + return sentinels.toString(); + } - protected static String name = "RedisSessionManager"; + public void setSentinels(String sentinels) { + if (null == sentinels) { + sentinels = ""; + } - protected String serializationStrategyClass = "com.orangefunction.tomcat.redissessions.JavaSerializer"; + String[] sentinelArray = sentinels.split(","); + this.sentinelSet = new HashSet<>(Arrays.asList(sentinelArray)); + } - protected EnumSet sessionPersistPoliciesSet = EnumSet.of(SessionPersistPolicy.DEFAULT); + private Set getSentinelSet() { + return this.sentinelSet; + } - /** - * The lifecycle event support for this component. - */ - protected LifecycleSupport lifecycle = new LifecycleSupport(this); + private String getSentinelMaster() { + return this.sentinelMaster; + } - public String getHost() { - return host; - } + public void setSentinelMaster(String master) { + this.sentinelMaster = master; + } - public void setHost(String host) { - this.host = host; - } + @Override + public int getRejectedSessions() { + // Essentially do nothing. + return 0; + } - public int getPort() { - return port; - } + @SuppressWarnings("EmptyMethod") + public void setRejectedSessions(int i) { + // Do nothing. + } - public void setPort(int port) { - this.port = port; - } + private Jedis acquireConnection() { + Jedis jedis = connectionPool.getResource(); - public int getDatabase() { - return database; - } + if (getDatabase() != 0) { + jedis.select(getDatabase()); + } - public void setDatabase(int database) { - this.database = database; - } + return jedis; + } - public int getTimeout() { - return timeout; - } + private void returnConnection(Jedis jedis, Boolean error) { + if (error) { + //noinspection deprecation + connectionPool.returnBrokenResource(jedis); + } else { + //noinspection deprecation + connectionPool.returnResource(jedis); + } + } - public void setTimeout(int timeout) { - this.timeout = timeout; - } + protected void returnConnection(Jedis jedis) { + returnConnection(jedis, false); + } - public String getPassword() { - return password; - } + @Override + public void load() throws ClassNotFoundException, IOException { - public void setPassword(String password) { - this.password = password; - } + } - public void setSerializationStrategyClass(String strategy) { - this.serializationStrategyClass = strategy; - } + @Override + public void unload() throws IOException { - public String getSessionPersistPolicies() { - StringBuilder policies = new StringBuilder(); - for (Iterator iter = this.sessionPersistPoliciesSet.iterator(); iter.hasNext();) { - SessionPersistPolicy policy = iter.next(); - policies.append(policy.name()); - if (iter.hasNext()) { - policies.append(","); - } } - return policies.toString(); - } - public void setSessionPersistPolicies(String sessionPersistPolicies) { - String[] policyArray = sessionPersistPolicies.split(","); - EnumSet policySet = EnumSet.of(SessionPersistPolicy.DEFAULT); - for (String policyName : policyArray) { - SessionPersistPolicy policy = SessionPersistPolicy.fromName(policyName); - policySet.add(policy); + /** + * Start this component and implement the requirements + * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. + * + * @throws LifecycleException if this component detects a fatal error + * that prevents this component from being used + */ + @Override + protected synchronized void startInternal() throws LifecycleException { + super.startInternal(); + + setState(LifecycleState.STARTING); + + Boolean attachedToValve = false; + for (Valve valve : getContext().getPipeline().getValves()) { + if (valve instanceof RedisSessionHandlerValve) { + this.handlerValve = (RedisSessionHandlerValve) valve; + this.handlerValve.setRedisSessionManager(this); + log.info("Attached to RedisSessionHandlerValve"); + attachedToValve = true; + break; + } + } + + if (!attachedToValve) { + String error = "Unable to attach to session handling valve; sessions cannot be saved after the request without the valve starting properly."; + log.fatal(error); + throw new LifecycleException(error); + } + + try { + initializeSerializer(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + log.fatal("Unable to load serializer", e); + throw new LifecycleException(e); + } + + log.info("Will expire sessions after " + getContext().getSessionTimeout() + " seconds"); + + initializeDatabaseConnection(); + this.getContext().setDistributable(true); + } - this.sessionPersistPoliciesSet = policySet; - } - - public boolean getSaveOnChange() { - return this.sessionPersistPoliciesSet.contains(SessionPersistPolicy.SAVE_ON_CHANGE); - } - - public boolean getAlwaysSaveAfterRequest() { - return this.sessionPersistPoliciesSet.contains(SessionPersistPolicy.ALWAYS_SAVE_AFTER_REQUEST); - } - - public String getSentinels() { - StringBuilder sentinels = new StringBuilder(); - for (Iterator iter = this.sentinelSet.iterator(); iter.hasNext();) { - sentinels.append(iter.next()); - if (iter.hasNext()) { - sentinels.append(","); - } - } - return sentinels.toString(); - } - - public void setSentinels(String sentinels) { - if (null == sentinels) { - sentinels = ""; - } - - String[] sentinelArray = sentinels.split(","); - this.sentinelSet = new HashSet(Arrays.asList(sentinelArray)); - } - - public Set getSentinelSet() { - return this.sentinelSet; - } - - public String getSentinelMaster() { - return this.sentinelMaster; - } - - public void setSentinelMaster(String master) { - this.sentinelMaster = master; - } - - @Override - public int getRejectedSessions() { - // Essentially do nothing. - return 0; - } - - public void setRejectedSessions(int i) { - // Do nothing. - } - - protected Jedis acquireConnection() { - Jedis jedis = connectionPool.getResource(); - - if (getDatabase() != 0) { - jedis.select(getDatabase()); - } - - return jedis; - } - - protected void returnConnection(Jedis jedis, Boolean error) { - if (error) { - connectionPool.returnBrokenResource(jedis); - } else { - connectionPool.returnResource(jedis); - } - } - - protected void returnConnection(Jedis jedis) { - returnConnection(jedis, false); - } - - @Override - public void load() throws ClassNotFoundException, IOException { - - } - - @Override - public void unload() throws IOException { - - } - - /** - * Add a lifecycle event listener to this component. - * - * @param listener The listener to add - */ - @Override - public void addLifecycleListener(LifecycleListener listener) { - lifecycle.addLifecycleListener(listener); - } - - /** - * Get the lifecycle listeners associated with this lifecycle. If this - * Lifecycle has no listeners registered, a zero-length array is returned. - */ - @Override - public LifecycleListener[] findLifecycleListeners() { - return lifecycle.findLifecycleListeners(); - } - - - /** - * Remove a lifecycle event listener from this component. - * - * @param listener The listener to remove - */ - @Override - public void removeLifecycleListener(LifecycleListener listener) { - lifecycle.removeLifecycleListener(listener); - } - - /** - * Start this component and implement the requirements - * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. - * - * @exception LifecycleException if this component detects a fatal error - * that prevents this component from being used - */ - @Override - protected synchronized void startInternal() throws LifecycleException { - super.startInternal(); - - setState(LifecycleState.STARTING); - - Boolean attachedToValve = false; - for (Valve valve : getContainer().getPipeline().getValves()) { - if (valve instanceof RedisSessionHandlerValve) { - this.handlerValve = (RedisSessionHandlerValve) valve; - this.handlerValve.setRedisSessionManager(this); - log.info("Attached to RedisSessionHandlerValve"); - attachedToValve = true; - break; - } - } - - if (!attachedToValve) { - String error = "Unable to attach to session handling valve; sessions cannot be saved after the request without the valve starting properly."; - log.fatal(error); - throw new LifecycleException(error); - } - - try { - initializeSerializer(); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { - log.fatal("Unable to load serializer", e); - throw new LifecycleException(e); - } - - log.info("Will expire sessions after " + getMaxInactiveInterval() + " seconds"); - - initializeDatabaseConnection(); - - setDistributable(true); - } - - - /** - * Stop this component and implement the requirements - * of {@link org.apache.catalina.util.LifecycleBase#stopInternal()}. - * - * @exception LifecycleException if this component detects a fatal error - * that prevents this component from being used - */ - @Override - protected synchronized void stopInternal() throws LifecycleException { - if (log.isDebugEnabled()) { - log.debug("Stopping"); - } - - setState(LifecycleState.STOPPING); - - try { - connectionPool.destroy(); - } catch(Exception e) { - // Do nothing. - } - - // Require a new random number generator if we are restarted - super.stopInternal(); - } - - @Override - public Session createSession(String requestedSessionId) { - RedisSession session = null; - String sessionId = null; - String jvmRoute = getJvmRoute(); - - Boolean error = true; - Jedis jedis = null; - try { - jedis = acquireConnection(); - - // Ensure generation of a unique session identifier. - if (null != requestedSessionId) { - sessionId = sessionIdWithJvmRoute(requestedSessionId, jvmRoute); - if (jedis.setnx(sessionId.getBytes(), NULL_SESSION) == 0L) { - sessionId = null; + + // /** + // * Add a lifecycle event listener to this component. + // * + // * @param listener The listener to add + // */ + // @Override + // public void addLifecycleListener(LifecycleListener listener) { + // lifecycle.addLifecycleListener(listener); + // } + // + // /** + // * Get the lifecycle listeners associated with this lifecycle. If this + // * Lifecycle has no listeners registered, a zero-length array is returned. + // */ + // @Override + // public LifecycleListener[] findLifecycleListeners() { + // return lifecycle.findLifecycleListeners(); + // } + // + + // /** + // * Remove a lifecycle event listener from this component. + // * + // * @param listener The listener to remove + // */ + // @Override + // public void removeLifecycleListener(LifecycleListener listener) { + // super. + // lifecycle.removeLifecycleListener(listener); + // } + + /** + * Stop this component and implement the requirements + * of {@link org.apache.catalina.util.LifecycleBase#stopInternal()}. + * + * @throws LifecycleException if this component detects a fatal error + * that prevents this component from being used + */ + @Override + protected synchronized void stopInternal() throws LifecycleException { + if (log.isDebugEnabled()) { + log.debug("Stopping"); + } + + setState(LifecycleState.STOPPING); + + try { + connectionPool.destroy(); + } catch (Exception e) { + // Do nothing. } - } else { - do { - sessionId = sessionIdWithJvmRoute(generateSessionId(), jvmRoute); - } while (jedis.setnx(sessionId.getBytes(), NULL_SESSION) == 0L); // 1 = key set; 0 = key already existed - } + + // Require a new random number generator if we are restarted + super.stopInternal(); + } + + @Override + public Session createSession(String requestedSessionId) { + RedisSession session = null; + String sessionId = null; + String jvmRoute = getJvmRoute(); + + Boolean error = true; + Jedis jedis = null; + try { + jedis = acquireConnection(); + + // Ensure generation of a unique session identifier. + if (null != requestedSessionId) { + sessionId = sessionIdWithJvmRoute(requestedSessionId, jvmRoute); + if (jedis.setnx(sessionId.getBytes(), NULL_SESSION) == 0L) { + sessionId = null; + } + } else { + do { + sessionId = sessionIdWithJvmRoute(generateSessionId(), jvmRoute); + } while (jedis.setnx(sessionId.getBytes(), NULL_SESSION) == 0L); // 1 = key set; 0 = key already existed + } /* Even though the key is set in Redis, we are not going to flag the current thread as having had the session persisted since @@ -360,526 +329,560 @@ public Session createSession(String requestedSessionId) { This ensures that the save(session) at the end of the request will serialize the session into Redis with 'set' instead of 'setnx'. */ - error = false; + error = false; + + if (null != sessionId) { + session = (RedisSession) createEmptySession(); + session.setNew(true); + session.setValid(true); + session.setCreationTime(System.currentTimeMillis()); + session.setMaxInactiveInterval(getContext().getSessionTimeout()); + session.setId(sessionId); + session.tellNew(); + } + + currentSession.set(session); + currentSessionId.set(sessionId); + currentSessionIsPersisted.set(false); + currentSessionSerializationMetadata.set(new SessionSerializationMetadata()); + + if (null != session) { + // try { + error = saveInternal(jedis, session, true); + // } catch (IOException ex) { + // log.error("Error saving newly created session: " + ex.getMessage()); + // currentSession.set(null); + // currentSessionId.set(null); + // session = null; + // } + } + } catch (Exception e) { + log.fatal("Session management not available!", e); + session = (RedisSession) createEmptySession(); + session.setNew(true); + session.setValid(true); + session.setCreationTime(System.currentTimeMillis()); + session.setMaxInactiveInterval(getContext().getSessionTimeout()); + session.setId(sessionId); + session.tellNew(); + } finally { + if (jedis != null) { + returnConnection(jedis, error); + } + } - if (null != sessionId) { - session = (RedisSession)createEmptySession(); - session.setNew(true); - session.setValid(true); - session.setCreationTime(System.currentTimeMillis()); - session.setMaxInactiveInterval(getMaxInactiveInterval()); - session.setId(sessionId); - session.tellNew(); - } + return session; + } - currentSession.set(session); - currentSessionId.set(sessionId); - currentSessionIsPersisted.set(false); - currentSessionSerializationMetadata.set(new SessionSerializationMetadata()); + private String sessionIdWithJvmRoute(String sessionId, String jvmRoute) { + if (jvmRoute != null) { + String jvmRoutePrefix = '.' + jvmRoute; + return sessionId.endsWith(jvmRoutePrefix) ? sessionId : sessionId + jvmRoutePrefix; + } + return sessionId; + } - if (null != session) { + @Override + public Session createEmptySession() { + return new RedisSession(this); + } + + @Override + public void add(Session session) { try { - error = saveInternal(jedis, session, true); + save(session); } catch (IOException ex) { - log.error("Error saving newly created session: " + ex.getMessage()); - currentSession.set(null); - currentSessionId.set(null); - session = null; - } - } - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } - } - - return session; - } - - private String sessionIdWithJvmRoute(String sessionId, String jvmRoute) { - if (jvmRoute != null) { - String jvmRoutePrefix = '.' + jvmRoute; - return sessionId.endsWith(jvmRoutePrefix) ? sessionId : sessionId + jvmRoutePrefix; - } - return sessionId; - } - - @Override - public Session createEmptySession() { - return new RedisSession(this); - } - - @Override - public void add(Session session) { - try { - save(session); - } catch (IOException ex) { - log.warn("Unable to add to session manager store: " + ex.getMessage()); - throw new RuntimeException("Unable to add to session manager store.", ex); - } - } - - @Override - public Session findSession(String id) throws IOException { - RedisSession session = null; - - if (null == id) { - currentSessionIsPersisted.set(false); - currentSession.set(null); - currentSessionSerializationMetadata.set(null); - currentSessionId.set(null); - } else if (id.equals(currentSessionId.get())) { - session = currentSession.get(); - } else { - byte[] data = loadSessionDataFromRedis(id); - if (data != null) { - DeserializedSessionContainer container = sessionFromSerializedData(id, data); - session = container.session; - currentSession.set(session); - currentSessionSerializationMetadata.set(container.metadata); - currentSessionIsPersisted.set(true); - currentSessionId.set(id); - } else { - currentSessionIsPersisted.set(false); - currentSession.set(null); - currentSessionSerializationMetadata.set(null); - currentSessionId.set(null); - } - } - - return session; - } - - public void clear() { - Jedis jedis = null; - Boolean error = true; - try { - jedis = acquireConnection(); - jedis.flushDB(); - error = false; - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } - } - } - - public int getSize() throws IOException { - Jedis jedis = null; - Boolean error = true; - try { - jedis = acquireConnection(); - int size = jedis.dbSize().intValue(); - error = false; - return size; - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } - } - } - - public String[] keys() throws IOException { - Jedis jedis = null; - Boolean error = true; - try { - jedis = acquireConnection(); - Set keySet = jedis.keys("*"); - error = false; - return keySet.toArray(new String[keySet.size()]); - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } - } - } - - public byte[] loadSessionDataFromRedis(String id) throws IOException { - Jedis jedis = null; - Boolean error = true; - - try { - log.trace("Attempting to load session " + id + " from Redis"); - - jedis = acquireConnection(); - byte[] data = jedis.get(id.getBytes()); - error = false; - - if (data == null) { - log.trace("Session " + id + " not found in Redis"); - } - - return data; - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } - } - } - - public DeserializedSessionContainer sessionFromSerializedData(String id, byte[] data) throws IOException { - log.trace("Deserializing session " + id + " from Redis"); - - if (Arrays.equals(NULL_SESSION, data)) { - log.error("Encountered serialized session " + id + " with data equal to NULL_SESSION. This is a bug."); - throw new IOException("Serialized session data was equal to NULL_SESSION"); - } - - RedisSession session = null; - SessionSerializationMetadata metadata = new SessionSerializationMetadata(); - - try { - session = (RedisSession)createEmptySession(); - - serializer.deserializeInto(data, session, metadata); - - session.setId(id); - session.setNew(false); - session.setMaxInactiveInterval(getMaxInactiveInterval()); - session.access(); - session.setValid(true); - session.resetDirtyTracking(); - - if (log.isTraceEnabled()) { - log.trace("Session Contents [" + id + "]:"); - Enumeration en = session.getAttributeNames(); - while(en.hasMoreElements()) { - log.trace(" " + en.nextElement()); + log.warn("Unable to add to session manager store: " + ex.getMessage()); + throw new RuntimeException("Unable to add to session manager store.", ex); } - } - } catch (ClassNotFoundException ex) { - log.fatal("Unable to deserialize into session", ex); - throw new IOException("Unable to deserialize into session", ex); } - return new DeserializedSessionContainer(session, metadata); - } + @Override + public Session findSession(String id) throws IOException { + RedisSession session = null; + + if (null == id) { + currentSessionIsPersisted.set(false); + currentSession.set(null); + currentSessionSerializationMetadata.set(null); + currentSessionId.set(null); + } else if (id.equals(currentSessionId.get())) { + session = currentSession.get(); + } else { + byte[] data = null; + try { + data = loadSessionDataFromRedis(id); + } catch (Exception e) { + log.fatal("Error - session Management not working!", e); + } + if (data != null) { + DeserializedSessionContainer container = sessionFromSerializedData(id, data); + session = container.session; + currentSession.set(session); + currentSessionSerializationMetadata.set(container.metadata); + currentSessionIsPersisted.set(true); + currentSessionId.set(id); + } else { + currentSessionIsPersisted.set(false); + currentSession.set(null); + currentSessionSerializationMetadata.set(null); + currentSessionId.set(null); + } + } + + return session; + } - public void save(Session session) throws IOException { - save(session, false); - } + public void clear() { + Jedis jedis = null; + Boolean error = true; + try { + jedis = acquireConnection(); + jedis.flushDB(); + error = false; + } finally { + if (jedis != null) { + returnConnection(jedis, error); + } + } + } - public void save(Session session, boolean forceSave) throws IOException { - Jedis jedis = null; - Boolean error = true; + public int getSize() { + Jedis jedis = null; + Boolean error = true; + try { + jedis = acquireConnection(); + int size = jedis.dbSize().intValue(); + error = false; + return size; + } finally { + if (jedis != null) { + returnConnection(jedis, error); + } + } + } - try { - jedis = acquireConnection(); - error = saveInternal(jedis, session, forceSave); - } catch (IOException e) { - throw e; - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } + public String[] keys() { + Jedis jedis = null; + Boolean error = true; + try { + jedis = acquireConnection(); + Set keySet = jedis.keys("*"); + error = false; + return keySet.toArray(new String[keySet.size()]); + } finally { + if (jedis != null) { + returnConnection(jedis, error); + } + } } - } - protected boolean saveInternal(Jedis jedis, Session session, boolean forceSave) throws IOException { - Boolean error = true; + private byte[] loadSessionDataFromRedis(String id) { + Jedis jedis = null; + Boolean error = true; + + try { + log.trace("Attempting to load session " + id + " from Redis"); - try { - log.trace("Saving session " + session + " into Redis"); + jedis = acquireConnection(); + byte[] data = jedis.get(id.getBytes()); + error = false; - RedisSession redisSession = (RedisSession)session; + if (data == null) { + log.trace("Session " + id + " not found in Redis"); + } - if (log.isTraceEnabled()) { - log.trace("Session Contents [" + redisSession.getId() + "]:"); - Enumeration en = redisSession.getAttributeNames(); - while(en.hasMoreElements()) { - log.trace(" " + en.nextElement()); + return data; + } finally { + if (jedis != null) { + returnConnection(jedis, error); + } } - } - - byte[] binaryId = redisSession.getId().getBytes(); - - Boolean isCurrentSessionPersisted; - SessionSerializationMetadata sessionSerializationMetadata = currentSessionSerializationMetadata.get(); - byte[] originalSessionAttributesHash = sessionSerializationMetadata.getSessionAttributesHash(); - byte[] sessionAttributesHash = null; - if ( - forceSave - || redisSession.isDirty() - || null == (isCurrentSessionPersisted = this.currentSessionIsPersisted.get()) - || !isCurrentSessionPersisted - || !Arrays.equals(originalSessionAttributesHash, (sessionAttributesHash = serializer.attributesHashFrom(redisSession))) - ) { - - log.trace("Save was determined to be necessary"); - - if (null == sessionAttributesHash) { - sessionAttributesHash = serializer.attributesHashFrom(redisSession); + } + + private DeserializedSessionContainer sessionFromSerializedData(String id, byte[] data) throws IOException { + log.trace("Deserializing session " + id + " from Redis"); + + if (Arrays.equals(NULL_SESSION, data)) { + log.error("Encountered serialized session " + id + " with data equal to NULL_SESSION. This is a bug."); + throw new IOException("Serialized session data was equal to NULL_SESSION"); } - SessionSerializationMetadata updatedSerializationMetadata = new SessionSerializationMetadata(); - updatedSerializationMetadata.setSessionAttributesHash(sessionAttributesHash); + RedisSession session; + SessionSerializationMetadata metadata = new SessionSerializationMetadata(); + + try { + session = (RedisSession) createEmptySession(); + + serializer.deserializeInto(data, session, metadata); + + session.setId(id); + session.setNew(false); + session.setMaxInactiveInterval(getContext().getSessionTimeout()); + session.access(); + session.setValid(true); + session.resetDirtyTracking(); + + if (log.isTraceEnabled()) { + log.trace("Session Contents [" + id + "]:"); + Enumeration en = session.getAttributeNames(); + while (en.hasMoreElements()) { + log.trace(" " + en.nextElement()); + } + } + } catch (ClassNotFoundException ex) { + log.fatal("Unable to deserialize into session", ex); + throw new IOException("Unable to deserialize into session", ex); + } + + return new DeserializedSessionContainer(session, metadata); + } + + private void save(Session session) throws IOException { + save(session, false); + } + + public void save(Session session, boolean forceSave) throws IOException { + Jedis jedis = null; + Boolean error = true; - jedis.set(binaryId, serializer.serializeFrom(redisSession, updatedSerializationMetadata)); + try { + jedis = acquireConnection(); + error = saveInternal(jedis, session, forceSave); + // } catch (IOException e) { + // throw e; + } finally { + if (jedis != null) { + returnConnection(jedis, error); + } + } + } - redisSession.resetDirtyTracking(); - currentSessionSerializationMetadata.set(updatedSerializationMetadata); - currentSessionIsPersisted.set(true); - } else { - log.trace("Save was determined to be unnecessary"); - } + private boolean saveInternal(Jedis jedis, Session session, boolean forceSave) { + Boolean error = true; + + try { + log.trace("Saving session " + session + " into Redis"); + + RedisSession redisSession = (RedisSession) session; + + if (log.isTraceEnabled()) { + log.trace("Session Contents [" + redisSession.getId() + "]:"); + Enumeration en = redisSession.getAttributeNames(); + while (en.hasMoreElements()) { + log.trace(" " + en.nextElement()); + } + } + + byte[] binaryId = redisSession.getId().getBytes(); + + Boolean isCurrentSessionPersisted; + SessionSerializationMetadata sessionSerializationMetadata = currentSessionSerializationMetadata.get(); + byte[] originalSessionAttributesHash = sessionSerializationMetadata.getSessionAttributesHash(); + byte[] sessionAttributesHash = null; + if ( + forceSave + || redisSession.isDirty() + || null == (isCurrentSessionPersisted = this.currentSessionIsPersisted.get()) + || !isCurrentSessionPersisted + || !Arrays.equals(originalSessionAttributesHash, (sessionAttributesHash = serializer.attributesHashFrom(redisSession))) + ) { + + log.trace("Save was determined to be necessary"); + + if (null == sessionAttributesHash) { + sessionAttributesHash = serializer.attributesHashFrom(redisSession); + } + + SessionSerializationMetadata updatedSerializationMetadata = new SessionSerializationMetadata(); + updatedSerializationMetadata.setSessionAttributesHash(sessionAttributesHash); + + jedis.set(binaryId, serializer.serializeFrom(redisSession, updatedSerializationMetadata)); + + redisSession.resetDirtyTracking(); + currentSessionSerializationMetadata.set(updatedSerializationMetadata); + currentSessionIsPersisted.set(true); + } else { + log.trace("Save was determined to be unnecessary"); + } + + log.trace("Setting expire timeout on session [" + redisSession.getId() + "] to " + getContext().getSessionTimeout()); + jedis.expire(binaryId, getContext().getSessionTimeout()); + + error = false; + + return error; + } catch (IOException e) { + log.error(e.getMessage()); + + throw e; + } finally { + return error; + } + } - log.trace("Setting expire timeout on session [" + redisSession.getId() + "] to " + getMaxInactiveInterval()); - jedis.expire(binaryId, getMaxInactiveInterval()); + @Override + public void remove(Session session) { + remove(session, false); + } - error = false; + @Override + public void remove(Session session, boolean update) { + Jedis jedis = null; + Boolean error = true; - return error; - } catch (IOException e) { - log.error(e.getMessage()); + log.trace("Removing session ID : " + session.getId()); - throw e; - } finally { - return error; + try { + jedis = acquireConnection(); + jedis.del(session.getId()); + error = false; + } finally { + if (jedis != null) { + returnConnection(jedis, error); + } + } } - } - @Override - public void remove(Session session) { - remove(session, false); - } + public void afterRequest() { + RedisSession redisSession = currentSession.get(); + if (redisSession != null) { + try { + if (redisSession.isValid()) { + log.trace("Request with session completed, saving session " + redisSession.getId()); + save(redisSession, getAlwaysSaveAfterRequest()); + } else { + log.trace("HTTP Session has been invalidated, removing :" + redisSession.getId()); + remove(redisSession); + } + } catch (Exception e) { + log.error("Error storing/removing session", e); + } finally { + currentSession.remove(); + currentSessionId.remove(); + currentSessionIsPersisted.remove(); + log.trace("Session removed from ThreadLocal :" + redisSession.getIdInternal()); + } + } + } - @Override - public void remove(Session session, boolean update) { - Jedis jedis = null; - Boolean error = true; + @Override + public void processExpires() { + // We are going to use Redis's ability to expire keys for session expiration. - log.trace("Removing session ID : " + session.getId()); + // Do nothing. + } - try { - jedis = acquireConnection(); - jedis.del(session.getId()); - error = false; - } finally { - if (jedis != null) { - returnConnection(jedis, error); - } + private void initializeDatabaseConnection() throws LifecycleException { + try { + if (getSentinelMaster() != null) { + Set sentinelSet = getSentinelSet(); + if (sentinelSet != null && sentinelSet.size() > 0) { + connectionPool = new JedisSentinelPool(getSentinelMaster(), sentinelSet, this.connectionPoolConfig, getTimeout(), getPassword()); + } else { + throw new LifecycleException("Error configuring Redis Sentinel connection pool: expected both `sentinelMaster` and `sentiels` to be configured"); + } + } else { + connectionPool = new JedisPool(this.connectionPoolConfig, getHost(), getPort(), getTimeout(), getPassword()); + } + } catch (Exception e) { + e.printStackTrace(); + throw new LifecycleException("Error connecting to Redis", e); + } } - } - public void afterRequest() { - RedisSession redisSession = currentSession.get(); - if (redisSession != null) { - try { - if (redisSession.isValid()) { - log.trace("Request with session completed, saving session " + redisSession.getId()); - save(redisSession, getAlwaysSaveAfterRequest()); - } else { - log.trace("HTTP Session has been invalidated, removing :" + redisSession.getId()); - remove(redisSession); + private void initializeSerializer() throws ClassNotFoundException, IllegalAccessException, InstantiationException { + log.info("Attempting to use serializer :" + serializationStrategyClass); + serializer = (Serializer) Class.forName(serializationStrategyClass).newInstance(); + + Loader loader = null; + + if (getContext() != null) { + loader = getContext().getLoader(); } - } catch (Exception e) { - log.error("Error storing/removing session", e); - } finally { - currentSession.remove(); - currentSessionId.remove(); - currentSessionIsPersisted.remove(); - log.trace("Session removed from ThreadLocal :" + redisSession.getIdInternal()); - } - } - } - - @Override - public void processExpires() { - // We are going to use Redis's ability to expire keys for session expiration. - - // Do nothing. - } - - private void initializeDatabaseConnection() throws LifecycleException { - try { - if (getSentinelMaster() != null) { - Set sentinelSet = getSentinelSet(); - if (sentinelSet != null && sentinelSet.size() > 0) { - connectionPool = new JedisSentinelPool(getSentinelMaster(), sentinelSet, this.connectionPoolConfig, getTimeout(), getPassword()); - } else { - throw new LifecycleException("Error configuring Redis Sentinel connection pool: expected both `sentinelMaster` and `sentiels` to be configured"); + + ClassLoader classLoader = null; + + if (loader != null) { + classLoader = loader.getClassLoader(); } - } else { - connectionPool = new JedisPool(this.connectionPoolConfig, getHost(), getPort(), getTimeout(), getPassword()); - } - } catch (Exception e) { - e.printStackTrace(); - throw new LifecycleException("Error connecting to Redis", e); + serializer.setClassLoader(classLoader); + } + + public int getConnectionPoolMaxTotal() { + return this.connectionPoolConfig.getMaxTotal(); } - } - private void initializeSerializer() throws ClassNotFoundException, IllegalAccessException, InstantiationException { - log.info("Attempting to use serializer :" + serializationStrategyClass); - serializer = (Serializer) Class.forName(serializationStrategyClass).newInstance(); - Loader loader = null; + // Connection Pool Config Accessors - if (getContainer() != null) { - loader = getContainer().getLoader(); + // - from org.apache.commons.pool2.impl.GenericObjectPoolConfig + + public void setConnectionPoolMaxTotal(int connectionPoolMaxTotal) { + this.connectionPoolConfig.setMaxTotal(connectionPoolMaxTotal); + } + + public int getConnectionPoolMaxIdle() { + return this.connectionPoolConfig.getMaxIdle(); + } + + public void setConnectionPoolMaxIdle(int connectionPoolMaxIdle) { + this.connectionPoolConfig.setMaxIdle(connectionPoolMaxIdle); + } + + public int getConnectionPoolMinIdle() { + return this.connectionPoolConfig.getMinIdle(); } - ClassLoader classLoader = null; + public void setConnectionPoolMinIdle(int connectionPoolMinIdle) { + this.connectionPoolConfig.setMinIdle(connectionPoolMinIdle); + } - if (loader != null) { - classLoader = loader.getClassLoader(); + public boolean getLifo() { + return this.connectionPoolConfig.getLifo(); } - serializer.setClassLoader(classLoader); - } - // Connection Pool Config Accessors + // - from org.apache.commons.pool2.impl.BaseObjectPoolConfig - // - from org.apache.commons.pool2.impl.GenericObjectPoolConfig + public void setLifo(boolean lifo) { + this.connectionPoolConfig.setLifo(lifo); + } - public int getConnectionPoolMaxTotal() { - return this.connectionPoolConfig.getMaxTotal(); - } + public long getMaxWaitMillis() { + return this.connectionPoolConfig.getMaxWaitMillis(); + } - public void setConnectionPoolMaxTotal(int connectionPoolMaxTotal) { - this.connectionPoolConfig.setMaxTotal(connectionPoolMaxTotal); - } + public void setMaxWaitMillis(long maxWaitMillis) { + this.connectionPoolConfig.setMaxWaitMillis(maxWaitMillis); + } - public int getConnectionPoolMaxIdle() { - return this.connectionPoolConfig.getMaxIdle(); - } + public long getMinEvictableIdleTimeMillis() { + return this.connectionPoolConfig.getMinEvictableIdleTimeMillis(); + } - public void setConnectionPoolMaxIdle(int connectionPoolMaxIdle) { - this.connectionPoolConfig.setMaxIdle(connectionPoolMaxIdle); - } + public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { + this.connectionPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + } + + public long getSoftMinEvictableIdleTimeMillis() { + return this.connectionPoolConfig.getSoftMinEvictableIdleTimeMillis(); + } + + public void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) { + this.connectionPoolConfig.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis); + } + + public int getNumTestsPerEvictionRun() { + return this.connectionPoolConfig.getNumTestsPerEvictionRun(); + } + + public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { + this.connectionPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun); + } + + public boolean getTestOnCreate() { + return this.connectionPoolConfig.getTestOnCreate(); + } - public int getConnectionPoolMinIdle() { - return this.connectionPoolConfig.getMinIdle(); - } + public void setTestOnCreate(boolean testOnCreate) { + this.connectionPoolConfig.setTestOnCreate(testOnCreate); + } - public void setConnectionPoolMinIdle(int connectionPoolMinIdle) { - this.connectionPoolConfig.setMinIdle(connectionPoolMinIdle); - } + public boolean getTestOnBorrow() { + return this.connectionPoolConfig.getTestOnBorrow(); + } + public void setTestOnBorrow(boolean testOnBorrow) { + this.connectionPoolConfig.setTestOnBorrow(testOnBorrow); + } - // - from org.apache.commons.pool2.impl.BaseObjectPoolConfig + public boolean getTestOnReturn() { + return this.connectionPoolConfig.getTestOnReturn(); + } - public boolean getLifo() { - return this.connectionPoolConfig.getLifo(); - } - public void setLifo(boolean lifo) { - this.connectionPoolConfig.setLifo(lifo); - } - public long getMaxWaitMillis() { - return this.connectionPoolConfig.getMaxWaitMillis(); - } + public void setTestOnReturn(boolean testOnReturn) { + this.connectionPoolConfig.setTestOnReturn(testOnReturn); + } - public void setMaxWaitMillis(long maxWaitMillis) { - this.connectionPoolConfig.setMaxWaitMillis(maxWaitMillis); - } + public boolean getTestWhileIdle() { + return this.connectionPoolConfig.getTestWhileIdle(); + } - public long getMinEvictableIdleTimeMillis() { - return this.connectionPoolConfig.getMinEvictableIdleTimeMillis(); - } + public void setTestWhileIdle(boolean testWhileIdle) { + this.connectionPoolConfig.setTestWhileIdle(testWhileIdle); + } - public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { - this.connectionPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); - } + public long getTimeBetweenEvictionRunsMillis() { + return this.connectionPoolConfig.getTimeBetweenEvictionRunsMillis(); + } - public long getSoftMinEvictableIdleTimeMillis() { - return this.connectionPoolConfig.getSoftMinEvictableIdleTimeMillis(); - } + public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { + this.connectionPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + } - public void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) { - this.connectionPoolConfig.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis); - } + public String getEvictionPolicyClassName() { + return this.connectionPoolConfig.getEvictionPolicyClassName(); + } - public int getNumTestsPerEvictionRun() { - return this.connectionPoolConfig.getNumTestsPerEvictionRun(); - } + public void setEvictionPolicyClassName(String evictionPolicyClassName) { + this.connectionPoolConfig.setEvictionPolicyClassName(evictionPolicyClassName); + } - public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { - this.connectionPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun); - } + public boolean getBlockWhenExhausted() { + return this.connectionPoolConfig.getBlockWhenExhausted(); + } - public boolean getTestOnCreate() { - return this.connectionPoolConfig.getTestOnCreate(); - } + public void setBlockWhenExhausted(boolean blockWhenExhausted) { + this.connectionPoolConfig.setBlockWhenExhausted(blockWhenExhausted); + } - public void setTestOnCreate(boolean testOnCreate) { - this.connectionPoolConfig.setTestOnCreate(testOnCreate); - } + public boolean getJmxEnabled() { + return this.connectionPoolConfig.getJmxEnabled(); + } - public boolean getTestOnBorrow() { - return this.connectionPoolConfig.getTestOnBorrow(); - } + public void setJmxEnabled(boolean jmxEnabled) { + this.connectionPoolConfig.setJmxEnabled(jmxEnabled); + } - public void setTestOnBorrow(boolean testOnBorrow) { - this.connectionPoolConfig.setTestOnBorrow(testOnBorrow); - } + public String getJmxNameBase() { + return this.connectionPoolConfig.getJmxNameBase(); + } - public boolean getTestOnReturn() { - return this.connectionPoolConfig.getTestOnReturn(); - } + public void setJmxNameBase(String jmxNameBase) { + this.connectionPoolConfig.setJmxNameBase(jmxNameBase); + } - public void setTestOnReturn(boolean testOnReturn) { - this.connectionPoolConfig.setTestOnReturn(testOnReturn); - } + public String getJmxNamePrefix() { + return this.connectionPoolConfig.getJmxNamePrefix(); + } - public boolean getTestWhileIdle() { - return this.connectionPoolConfig.getTestWhileIdle(); - } + public void setJmxNamePrefix(String jmxNamePrefix) { + this.connectionPoolConfig.setJmxNamePrefix(jmxNamePrefix); + } - public void setTestWhileIdle(boolean testWhileIdle) { - this.connectionPoolConfig.setTestWhileIdle(testWhileIdle); - } - - public long getTimeBetweenEvictionRunsMillis() { - return this.connectionPoolConfig.getTimeBetweenEvictionRunsMillis(); - } - - public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { - this.connectionPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); - } - - public String getEvictionPolicyClassName() { - return this.connectionPoolConfig.getEvictionPolicyClassName(); - } - - public void setEvictionPolicyClassName(String evictionPolicyClassName) { - this.connectionPoolConfig.setEvictionPolicyClassName(evictionPolicyClassName); - } - - public boolean getBlockWhenExhausted() { - return this.connectionPoolConfig.getBlockWhenExhausted(); - } - - public void setBlockWhenExhausted(boolean blockWhenExhausted) { - this.connectionPoolConfig.setBlockWhenExhausted(blockWhenExhausted); - } - - public boolean getJmxEnabled() { - return this.connectionPoolConfig.getJmxEnabled(); - } - - public void setJmxEnabled(boolean jmxEnabled) { - this.connectionPoolConfig.setJmxEnabled(jmxEnabled); - } - public String getJmxNameBase() { - return this.connectionPoolConfig.getJmxNameBase(); - } - public void setJmxNameBase(String jmxNameBase) { - this.connectionPoolConfig.setJmxNameBase(jmxNameBase); - } - - public String getJmxNamePrefix() { - return this.connectionPoolConfig.getJmxNamePrefix(); - } - - public void setJmxNamePrefix(String jmxNamePrefix) { - this.connectionPoolConfig.setJmxNamePrefix(jmxNamePrefix); - } + enum SessionPersistPolicy { + DEFAULT, + SAVE_ON_CHANGE, + ALWAYS_SAVE_AFTER_REQUEST; + + static SessionPersistPolicy fromName(String name) { + for (SessionPersistPolicy policy : SessionPersistPolicy.values()) { + if (policy.name().equalsIgnoreCase(name)) { + return policy; + } + } + throw new IllegalArgumentException("Invalid session persist policy [" + name + "]. Must be one of " + Arrays.asList(SessionPersistPolicy.values()) + "."); + } + } } class DeserializedSessionContainer { - public final RedisSession session; - public final SessionSerializationMetadata metadata; - public DeserializedSessionContainer(RedisSession session, SessionSerializationMetadata metadata) { - this.session = session; - this.metadata = metadata; - } + public final RedisSession session; + public final SessionSerializationMetadata metadata; + + public DeserializedSessionContainer(RedisSession session, SessionSerializationMetadata metadata) { + this.session = session; + this.metadata = metadata; + } } diff --git a/src/main/java/com/orangefunction/tomcat/redissessions/Serializer.java b/src/main/java/com/orangefunction/tomcat/redissessions/Serializer.java index b6d1161a..ffa22d76 100644 --- a/src/main/java/com/orangefunction/tomcat/redissessions/Serializer.java +++ b/src/main/java/com/orangefunction/tomcat/redissessions/Serializer.java @@ -1,6 +1,5 @@ package com.orangefunction.tomcat.redissessions; -import javax.servlet.http.HttpSession; import java.io.IOException; public interface Serializer { diff --git a/src/main/java/com/orangefunction/tomcat/redissessions/SessionSerializationMetadata.java b/src/main/java/com/orangefunction/tomcat/redissessions/SessionSerializationMetadata.java index 7d3d9276..5a415a21 100644 --- a/src/main/java/com/orangefunction/tomcat/redissessions/SessionSerializationMetadata.java +++ b/src/main/java/com/orangefunction/tomcat/redissessions/SessionSerializationMetadata.java @@ -1,42 +1,47 @@ package com.orangefunction.tomcat.redissessions; -import java.io.*; - +import java.io.IOException; +import java.io.ObjectStreamException; +import java.io.Serializable; +@SuppressWarnings("serial") public class SessionSerializationMetadata implements Serializable { - private byte[] sessionAttributesHash; + private static final long serialVersionUID = 4817120933319990092L; + + private byte[] sessionAttributesHash; - public SessionSerializationMetadata() { - this.sessionAttributesHash = new byte[0]; - } + public SessionSerializationMetadata() { + this.sessionAttributesHash = new byte[0]; + } - public byte[] getSessionAttributesHash() { - return sessionAttributesHash; - } + public byte[] getSessionAttributesHash() { + return sessionAttributesHash; + } - public void setSessionAttributesHash(byte[] sessionAttributesHash) { - this.sessionAttributesHash = sessionAttributesHash; - } + public void setSessionAttributesHash(byte[] sessionAttributesHash) { + this.sessionAttributesHash = sessionAttributesHash; + } - public void copyFieldsFrom(SessionSerializationMetadata metadata) { - this.setSessionAttributesHash(metadata.getSessionAttributesHash()); - } + public void copyFieldsFrom(SessionSerializationMetadata metadata) { + this.setSessionAttributesHash(metadata.getSessionAttributesHash()); + } - private void writeObject(java.io.ObjectOutputStream out) throws IOException { - out.writeInt(sessionAttributesHash.length); - out.write(this.sessionAttributesHash); - } + private void writeObject(java.io.ObjectOutputStream out) throws IOException { + out.writeInt(sessionAttributesHash.length); + out.write(this.sessionAttributesHash); + } - private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { - int hashLength = in.readInt(); - byte[] sessionAttributesHash = new byte[hashLength]; - in.read(sessionAttributesHash, 0, hashLength); - this.sessionAttributesHash = sessionAttributesHash; - } + private void readObject(java.io.ObjectInputStream in) throws IOException, + ClassNotFoundException { + int hashLength = in.readInt(); + byte[] sessionAttributesHash = new byte[hashLength]; + in.read(sessionAttributesHash, 0, hashLength); + this.sessionAttributesHash = sessionAttributesHash; + } - private void readObjectNoData() throws ObjectStreamException { - this.sessionAttributesHash = new byte[0]; - } + private void readObjectNoData() { + this.sessionAttributesHash = new byte[0]; + } } diff --git a/vagrant/tomcat-redis-example/.gitignore b/vagrant/tomcat-redis-example/.gitignore deleted file mode 100644 index cbccf1ea..00000000 --- a/vagrant/tomcat-redis-example/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -*~ -*# -.#* -\#*# -.*.sw[a-z] -*.un~ -pkg/ - -# Berkshelf -.vagrant -/cookbooks -Berksfile.lock - -# Bundler -Gemfile.lock -bin/* -.bundle/* - -.kitchen/ -.kitchen.local.yml diff --git a/vagrant/tomcat-redis-example/.kitchen.yml b/vagrant/tomcat-redis-example/.kitchen.yml deleted file mode 100644 index 8e312076..00000000 --- a/vagrant/tomcat-redis-example/.kitchen.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -driver: - name: vagrant - -provisioner: - name: chef_solo - -platforms: - - name: ubuntu-12.04 - - name: centos-6.4 - -suites: - - name: default - run_list: - attributes: diff --git a/vagrant/tomcat-redis-example/Berksfile b/vagrant/tomcat-redis-example/Berksfile deleted file mode 100644 index e1d49d3f..00000000 --- a/vagrant/tomcat-redis-example/Berksfile +++ /dev/null @@ -1,5 +0,0 @@ -source "https://api.berkshelf.com" - -metadata - -cookbook 'java', github: 'agileorbit-cookbooks/java', branch: 'master' diff --git a/vagrant/tomcat-redis-example/Gemfile b/vagrant/tomcat-redis-example/Gemfile deleted file mode 100644 index 55f8096e..00000000 --- a/vagrant/tomcat-redis-example/Gemfile +++ /dev/null @@ -1,18 +0,0 @@ -source 'https://rubygems.org' - -gem 'berkshelf' - -# Uncomment these lines if you want to live on the Edge: -# -# group :development do -# gem "berkshelf", github: "berkshelf/berkshelf" -# gem "vagrant", github: "mitchellh/vagrant", tag: "v1.5.2" -# end -# -# group :plugins do -# gem "vagrant-berkshelf", github: "berkshelf/vagrant-berkshelf" -# gem "vagrant-omnibus", github: "schisamo/vagrant-omnibus" -# end - -gem 'test-kitchen' -gem 'kitchen-vagrant' diff --git a/vagrant/tomcat-redis-example/Thorfile b/vagrant/tomcat-redis-example/Thorfile deleted file mode 100644 index b23ee163..00000000 --- a/vagrant/tomcat-redis-example/Thorfile +++ /dev/null @@ -1,12 +0,0 @@ -# encoding: utf-8 - -require 'bundler' -require 'bundler/setup' -require 'berkshelf/thor' - -begin - require 'kitchen/thor_tasks' - Kitchen::ThorTasks.new -rescue LoadError - puts ">>>>> Kitchen gem not loaded, omitting tasks" unless ENV['CI'] -end diff --git a/vagrant/tomcat-redis-example/Vagrantfile b/vagrant/tomcat-redis-example/Vagrantfile deleted file mode 100644 index 0a592918..00000000 --- a/vagrant/tomcat-redis-example/Vagrantfile +++ /dev/null @@ -1,106 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! -VAGRANTFILE_API_VERSION = "2" - -Vagrant.require_version ">= 1.5.0" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - # All Vagrant configuration is done here. The most common configuration - # options are documented and commented below. For a complete reference, - # please see the online documentation at vagrantup.com. - - config.vm.hostname = "tomcat-redis-example-berkshelf" - - # Set the version of chef to install using the vagrant-omnibus plugin - config.omnibus.chef_version = '11.10' - - # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = "ubuntu/trusty64" - - # The url from where the 'config.vm.box' box will be fetched if it - # doesn't already exist on the user's system. - config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box" - - # Assign this VM to a host-only network IP, allowing you to access it - # via the IP. Host-only networks can talk to the host machine as well as - # any other machines on the same network, but cannot be accessed (through this - # network interface) by any external networks. - config.vm.network :private_network, type: "dhcp" - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # config.vm.network "forwarded_port", guest: 80, host: 8080 - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - config.vm.synced_folder "../../", "/opt/tomcat-redis-session-manager" - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider :virtualbox do |vb| - # # Don't boot with headless mode - # vb.gui = true - # - # # Use VBoxManage to customize the VM. For example to change memory: - # vb.customize ["modifyvm", :id, "--memory", "1024"] - # end - # - # View the documentation for the provider you're using for more - # information on available options. - - # The path to the Berksfile to use with Vagrant Berkshelf - # config.berkshelf.berksfile_path = "./Berksfile" - - # Enabling the Berkshelf plugin. To enable this globally, add this configuration - # option to your ~/.vagrant.d/Vagrantfile file - config.berkshelf.enabled = true - - # An array of symbols representing groups of cookbook described in the Vagrantfile - # to exclusively install and copy to Vagrant's shelf. - # config.berkshelf.only = [] - - # An array of symbols representing groups of cookbook described in the Vagrantfile - # to skip installing and copying to Vagrant's shelf. - # config.berkshelf.except = [] - - config.vm.provision :chef_solo do |chef| - chef.json = { - mysql: { - server_root_password: 'rootpass', - server_debian_password: 'debpass', - server_repl_password: 'replpass' - } - } - - chef.run_list = [ - "recipe[tomcat-redis-example::default]" - ] - end - - if Vagrant.has_plugin?("vagrant-cachier") - # Configure cached packages to be shared between instances of the same base box. - # More info on http://fgrehm.viewdocs.io/vagrant-cachier/usage - config.cache.scope = :box - - # If you are using VirtualBox, you might want to use that to enable NFS for - # shared folders. This is also very useful for vagrant-libvirt if you want - # bi-directional sync - config.cache.synced_folder_opts = { - type: :nfs, - # The nolock option can be useful for an NFSv3 client that wants to avoid the - # NLM sideband protocol. Without this option, apt-get might hang if it tries - # to lock files needed for /var/cache/* operations. All of this can be avoided - # by using NFSv4 everywhere. Please note that the tcp option is not the default. - mount_options: ['rw', 'vers=3', 'tcp', 'nolock'] - } - # For more information please check http://docs.vagrantup.com/v2/synced-folders/basic_usage.html - end -end diff --git a/vagrant/tomcat-redis-example/chefignore b/vagrant/tomcat-redis-example/chefignore deleted file mode 100644 index 138a808b..00000000 --- a/vagrant/tomcat-redis-example/chefignore +++ /dev/null @@ -1,94 +0,0 @@ -# Put files/directories that should be ignored in this file when uploading -# or sharing to the community site. -# Lines that start with '# ' are comments. - -# OS generated files # -###################### -.DS_Store -Icon? -nohup.out -ehthumbs.db -Thumbs.db - -# SASS # -######## -.sass-cache - -# EDITORS # -########### -\#* -.#* -*~ -*.sw[a-z] -*.bak -REVISION -TAGS* -tmtags -*_flymake.* -*_flymake -*.tmproj -.project -.settings -mkmf.log - -## COMPILED ## -############## -a.out -*.o -*.pyc -*.so -*.com -*.class -*.dll -*.exe -*/rdoc/ - -# Testing # -########### -.watchr -.rspec -spec/* -spec/fixtures/* -test/* -features/* -Guardfile -Procfile - -# SCM # -####### -.git -*/.git -.gitignore -.gitmodules -.gitconfig -.gitattributes -.svn -*/.bzr/* -*/.hg/* -*/.svn/* - -# Berkshelf # -############# -cookbooks/* -tmp - -# Cookbooks # -############# -CONTRIBUTING -CHANGELOG* - -# Strainer # -############ -Colanderfile -Strainerfile -.colander -.strainer - -# Vagrant # -########### -.vagrant -Vagrantfile - -# Travis # -########## -.travis.yml diff --git a/vagrant/tomcat-redis-example/metadata.rb b/vagrant/tomcat-redis-example/metadata.rb deleted file mode 100644 index 04036947..00000000 --- a/vagrant/tomcat-redis-example/metadata.rb +++ /dev/null @@ -1,15 +0,0 @@ -name 'tomcat-redis-example' -maintainer 'James Coleman' -maintainer_email 'jtc331@gmail.com' -license 'MIT' -description 'Installs/Configures tomcat-redis-example' -long_description 'Installs/Configures tomcat-redis-example' -version '0.1.0' - -depends 'apt', '~> 2.4' -depends 'tomcat', '~> 0.16.2' -depends 'redisio', '~> 2.2.3' - -%w{ ubuntu debian }.each do |os| - supports os -end \ No newline at end of file diff --git a/vagrant/tomcat-redis-example/recipes/default.rb b/vagrant/tomcat-redis-example/recipes/default.rb deleted file mode 100644 index f2f4396a..00000000 --- a/vagrant/tomcat-redis-example/recipes/default.rb +++ /dev/null @@ -1,44 +0,0 @@ -node.set['java']['jdk_version'] = '7' - -node.set["tomcat"]["base_version"] = 7 -node.set['tomcat']['user'] = "tomcat#{node["tomcat"]["base_version"]}" -node.set['tomcat']['group'] = "tomcat#{node["tomcat"]["base_version"]}" -node.set['tomcat']['home'] = "/usr/share/tomcat#{node["tomcat"]["base_version"]}" -node.set['tomcat']['base'] = "/var/lib/tomcat#{node["tomcat"]["base_version"]}" -node.set['tomcat']['config_dir'] = "/etc/tomcat#{node["tomcat"]["base_version"]}" -node.set['tomcat']['log_dir'] = "/var/log/tomcat#{node["tomcat"]["base_version"]}" -node.set['tomcat']['tmp_dir'] = "/tmp/tomcat#{node["tomcat"]["base_version"]}-tmp" -node.set['tomcat']['work_dir'] = "/var/cache/tomcat#{node["tomcat"]["base_version"]}" -node.set['tomcat']['context_dir'] = "#{node["tomcat"]["config_dir"]}/Catalina/localhost" -node.set['tomcat']['webapp_dir'] = "/var/lib/tomcat#{node["tomcat"]["base_version"]}/webapps" -node.set['tomcat']['lib_dir'] = "#{node["tomcat"]["home"]}/lib" -node.set['tomcat']['endorsed_dir'] = "#{node["tomcat"]["lib_dir"]}/endorsed" - -#Chef::Log.info "node: #{node.to_hash.inspect}" - -include_recipe 'redisio' -include_recipe 'redisio::enable' - -include_recipe 'tomcat' - -lib_dir = File.join(node['tomcat']['base'], 'lib') - -directory(lib_dir) do - user node['tomcat']['user'] - group node['tomcat']['group'] -end - -remote_file(File.join(lib_dir, 'spark-core-1.1.1.jar')) do - source 'http://central.maven.org/maven2/com/sparkjava/spark-core/1.1.1/spark-core-1.1.1.jar' - action :create_if_missing -end - -remote_file(File.join(lib_dir, 'commons-pool2-2.2.jar')) do - source 'http://central.maven.org/maven2/org/apache/commons/commons-pool2/2.2/commons-pool2-2.2.jar' - action :create_if_missing -end - -remote_file(File.join(lib_dir, 'jedis-2.5.2.jar')) do - source 'http://central.maven.org/maven2/redis/clients/jedis/2.5.2/jedis-2.5.2.jar' - action :create_if_missing -end