Add GemFire Support
Fixes GH PR #148 and PR #308 implementing a GemFire Adapter to support clustered HttpSessions in Spring Session. * Resolve SGF-373 - Implement a Spring Session Adapter for GemFire backing a HttpSession similar to the Redis support. * Add Spring Session annotation to enable GemFire support with @EnableGemFireHttpSession. * Add extesion of SpringHttpSessionConfiguration to configure GemFire using GemFireHttpSessionConfiguration. * Add implementation of SessionRepository to access clustered, replicated HttpSession state in GemFire with GemFireOperationsSessionRepository. * Utilize GemFire Data Serialization framework to both replicate HttpSession state information as well as handle deltas. * Utilize GemFire OQL query to lookup arbitrary Session attributes by name, and in particular the user authenticated principal name. * Implment unit and integration tests, and in particular, tests for both peer-to-peer (p2p) and client/server topologies. * Set initial Spring Data GemFire version to 1.7.2.RELEASE, which depends on Pivotal GemFire 8.1.0. * Add documentation, Javadoc and samples along with additional Integration Tests. Fixes gh-148
This commit is contained in:
22
samples/httpsession-gemfire-p2p/build.gradle
Normal file
22
samples/httpsession-gemfire-p2p/build.gradle
Normal file
@@ -0,0 +1,22 @@
|
||||
apply from: JAVA_GRADLE
|
||||
apply from: TOMCAT_7_GRADLE
|
||||
|
||||
tasks.findByPath("artifactoryPublish")?.enabled = false
|
||||
|
||||
sonarRunner {
|
||||
skipProject = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-session-data-gemfire'),
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
jstlDependencies
|
||||
|
||||
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
|
||||
|
||||
testCompile "junit:junit:$junitVersion"
|
||||
|
||||
integrationTestCompile gebDependencies
|
||||
|
||||
integrationTestRuntime "org.springframework.shell:spring-shell:1.0.0.RELEASE"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample
|
||||
|
||||
import geb.spock.*
|
||||
import sample.pages.HomePage;
|
||||
import spock.lang.Stepwise
|
||||
import pages.*
|
||||
|
||||
/**
|
||||
* Tests the CAS sample application using service tickets.
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@Stepwise
|
||||
class AttributeTests extends GebReportingSpec {
|
||||
def 'first visit no attributes'() {
|
||||
when:
|
||||
to HomePage
|
||||
then:
|
||||
attributes.empty
|
||||
}
|
||||
|
||||
def 'create attribute'() {
|
||||
when:
|
||||
createAttribute('a','b')
|
||||
then:
|
||||
attributes.size() == 1
|
||||
attributes[0].name == 'a'
|
||||
attributes[0].value == 'b'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample.pages
|
||||
|
||||
import geb.*
|
||||
|
||||
/**
|
||||
* The home page
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class HomePage extends Page {
|
||||
static url = ''
|
||||
static at = { assert driver.title == 'Session Attributes'; true}
|
||||
static content = {
|
||||
form { $('form') }
|
||||
submit { $('input[type=submit]') }
|
||||
createAttribute(required:false) { name, value ->
|
||||
form.attributeName = name
|
||||
form.attributeValue = value
|
||||
submit.click(HomePage)
|
||||
}
|
||||
attributes { moduleList AttributeRow, $("table tr").tail() }
|
||||
}
|
||||
}
|
||||
class AttributeRow extends Module {
|
||||
static content = {
|
||||
cell { $("td", it) }
|
||||
name { cell(0).text() }
|
||||
value { cell(1).text() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
|
||||
// tag::class[]
|
||||
@EnableGemFireHttpSession // <1>
|
||||
public class Config {
|
||||
|
||||
@Bean
|
||||
Properties gemfireProperties() { // <2>
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", "GemFireP2PHttpSessionSample");
|
||||
gemfireProperties.setProperty("mcast-port", "0");
|
||||
gemfireProperties.setProperty("log-level",
|
||||
System.getProperty("sample.httpsession.gemfire.log-level", "warning"));
|
||||
gemfireProperties.setProperty("jmx-manager", "true");
|
||||
gemfireProperties.setProperty("jmx-manager-start", "true");
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheFactoryBean gemfireCache() { // <3>
|
||||
CacheFactoryBean gemfireCache = new CacheFactoryBean();
|
||||
|
||||
gemfireCache.setProperties(gemfireProperties());
|
||||
gemfireCache.setUseBeanFactoryLocator(false);
|
||||
|
||||
return gemfireCache;
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample;
|
||||
|
||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||
|
||||
// tag::class[]
|
||||
public class Initializer
|
||||
extends AbstractHttpSessionApplicationInitializer { // <1>
|
||||
|
||||
public Initializer() {
|
||||
super(Config.class); // <2>
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package sample;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
// tag::class[]
|
||||
@WebServlet("/session")
|
||||
public class SessionServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
String attributeName = request.getParameter("attributeName");
|
||||
String attributeValue = request.getParameter("attributeValue");
|
||||
request.getSession().setAttribute(attributeName, attributeValue);
|
||||
response.sendRedirect(request.getContextPath() + "/");
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 2878267318695777395L;
|
||||
}
|
||||
// tag::end[]
|
||||
5
samples/httpsession-gemfire-p2p/src/main/webapp/assets/bootstrap.min.css
vendored
Normal file
5
samples/httpsession-gemfire-p2p/src/main/webapp/assets/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
48
samples/httpsession-gemfire-p2p/src/main/webapp/index.jsp
Normal file
48
samples/httpsession-gemfire-p2p/src/main/webapp/index.jsp
Normal file
@@ -0,0 +1,48 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Session Attributes</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap.min.css">
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Description</h1>
|
||||
<p>This application demonstrates how to use a GemFire instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.</p>
|
||||
|
||||
<h1>Try it</h1>
|
||||
|
||||
<form class="form-inline" role="form" action="./session" method="post">
|
||||
<label for="attributeName">Attribute Name</label>
|
||||
<input id="attributeName" type="text" name="attributeName"/>
|
||||
<label for="attributeValue">Attribute Value</label>
|
||||
<input id="attributeValue" type="text" name="attributeValue"/>
|
||||
<input type="submit" value="Set Attribute"/>
|
||||
</form>
|
||||
|
||||
<hr/>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute Name</th>
|
||||
<th>Attribute Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:forEach items="${sessionScope}" var="attr">
|
||||
<tr>
|
||||
<td><c:out value="${attr.key}"/></td>
|
||||
<td><c:out value="${attr.value}"/></td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user