Fixup documentation and samples.
This commit is contained in:
@@ -19,11 +19,6 @@ dependencies {
|
||||
|
||||
testCompile "org.springframework.boot:spring-boot-starter-test"
|
||||
testCompile seleniumDependencies
|
||||
// testCompile 'org.seleniumhq.selenium:htmlunit-driver'
|
||||
// testCompile 'org.seleniumhq.selenium:selenium-api'
|
||||
// testCompile 'org.seleniumhq.selenium:selenium-java'
|
||||
// testCompile 'org.seleniumhq.selenium:selenium-remote-driver'
|
||||
// testCompile 'org.seleniumhq.selenium:selenium-support'
|
||||
|
||||
integrationTestCompile seleniumDependencies
|
||||
|
||||
@@ -45,7 +40,7 @@ task runGemFireServer() {
|
||||
doLast {
|
||||
ext.port = reservePort()
|
||||
|
||||
println "Starting GemFire Server on port [$port] ..."
|
||||
println "Starting Apache Geode Server on port [$port] ..."
|
||||
|
||||
def out = new StringBuilder()
|
||||
def err = new StringBuilder()
|
||||
@@ -56,9 +51,7 @@ task runGemFireServer() {
|
||||
'java', '-server', '-ea', '-classpath', classpath,
|
||||
//"-Dgemfire.log-file=gemfire-server.log",
|
||||
//"-Dgemfire.log-level=config",
|
||||
"-Dspring-session-data-gemfire.cache.server.port=$port",
|
||||
"-Dspring-session-data-gemfire.log.level="
|
||||
+ System.getProperty('spring-session-data-gemfire.log.level', 'warning'),
|
||||
"-Dspring.session.data.geode.cache.server.port=$port",
|
||||
'sample.server.GemFireServer'
|
||||
]
|
||||
|
||||
@@ -83,11 +76,10 @@ integrationTest {
|
||||
systemProperties['server.port'] = port
|
||||
//systemProperties['gemfire.log-file'] = "gemfire-client.log"
|
||||
//systemProperties['gemfire.log-level'] = "config"
|
||||
systemProperties['spring-session-data-gemfire.cache.server.port'] = runGemFireServer.port
|
||||
systemProperties['spring-session-data-gemfire.log.level'] = System.getProperty("spring-session-data-gemfire.log.level", "warning")
|
||||
systemProperties['spring.session.data.geode.cache.server.port'] = runGemFireServer.port
|
||||
}
|
||||
doLast {
|
||||
println 'Stopping GemFire Server...'
|
||||
println 'Stopping Apache Geode Server...'
|
||||
runGemFireServer.process?.destroyForcibly()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package sample.client;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
@@ -26,44 +23,21 @@ import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.apache.geode.cache.client.internal.PoolImpl;
|
||||
import org.apache.geode.management.membership.ClientMembership;
|
||||
import org.apache.geode.management.membership.ClientMembershipEvent;
|
||||
import org.apache.geode.management.membership.ClientMembershipListenerAdapter;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.support.ConnectionEndpoint;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -88,18 +62,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
* @since 1.2.1
|
||||
*/
|
||||
// tag::class[]
|
||||
@SpringBootApplication
|
||||
@Controller
|
||||
@EnableGemFireHttpSession(poolName = "DEFAULT")// <1>
|
||||
@SuppressWarnings("unused")
|
||||
@SpringBootApplication // <1>
|
||||
@Controller // <2>
|
||||
public class Application {
|
||||
|
||||
static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
|
||||
|
||||
static final CountDownLatch LATCH = new CountDownLatch(1);
|
||||
|
||||
static final String DEFAULT_GEMFIRE_LOG_LEVEL = "config";
|
||||
static final String GEMFIRE_DEFAULT_POOL_NAME = "DEFAULT";
|
||||
static final String INDEX_TEMPLATE_VIEW_NAME = "index";
|
||||
static final String PING_RESPONSE = "PONG";
|
||||
static final String REQUEST_COUNT_ATTRIBUTE_NAME = "requestCount";
|
||||
@@ -108,197 +74,32 @@ public class Application {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class GemFireConfiguration {
|
||||
@ClientCacheApplication(name = "SpringSessionDataGeodeClientBootSample", logLevel = "warning",
|
||||
pingInterval = 5000L, readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true) // <3>
|
||||
@EnableGemFireHttpSession(poolName = "DEFAULT") // <4>
|
||||
static class ClientCacheConfiguration extends IntegrationTestConfiguration {
|
||||
|
||||
// Required to resolve property placeholders in Spring @Value annotations.
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() { // <2>
|
||||
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", applicationName());
|
||||
//gemfireProperties.setProperty("log-file", "gemfire-client.log");
|
||||
gemfireProperties.setProperty("log-level", logLevel());
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
String applicationName() {
|
||||
return "spring-session-data-gemfire-boot-sample.".concat(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
String logLevel() {
|
||||
return System.getProperty("spring-session-data-gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientCacheFactoryBean gemfireCache(
|
||||
@Value("${spring-session-data-gemfire.cache.server.host:localhost}") String host,
|
||||
@Value("${spring-session-data-gemfire.cache.server.port:40404}") int port) { // <3>
|
||||
ClientCacheConfigurer clientCacheServerPortConfigurer(
|
||||
@Value("${spring.session.data.geode.cache.server.port:40404}") int port) { // <5>
|
||||
|
||||
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
|
||||
|
||||
gemfireCache.setClose(true);
|
||||
gemfireCache.setProperties(gemfireProperties());
|
||||
|
||||
// GemFire Pool settings <4>
|
||||
gemfireCache.setKeepAlive(false);
|
||||
gemfireCache.setPingInterval(TimeUnit.SECONDS.toMillis(5));
|
||||
gemfireCache.setReadTimeout(intValue(TimeUnit.SECONDS.toMillis(15)));
|
||||
gemfireCache.setRetryAttempts(1);
|
||||
gemfireCache.setSubscriptionEnabled(true);
|
||||
gemfireCache.setThreadLocalConnections(false);
|
||||
gemfireCache.setServers(Collections.singletonList(newConnectionEndpoint(host, port)));
|
||||
|
||||
registerClientMembershipListener(); // <5>
|
||||
|
||||
return gemfireCache;
|
||||
}
|
||||
|
||||
int intValue(Number number) {
|
||||
return number.intValue();
|
||||
}
|
||||
|
||||
ConnectionEndpoint newConnectionEndpoint(String host, int port) {
|
||||
return new ConnectionEndpoint(host, port);
|
||||
}
|
||||
|
||||
void registerClientMembershipListener() {
|
||||
|
||||
ClientMembership.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void memberJoined(ClientMembershipEvent event) {
|
||||
LATCH.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Bean(name = "Example")
|
||||
@Profile("debug")
|
||||
ClientRegionFactoryBean<String, Object> exampleRegion(ClientCache gemfireCache) {
|
||||
|
||||
ClientRegionFactoryBean<String, Object> exampleRegionFactory = new ClientRegionFactoryBean<>();
|
||||
|
||||
exampleRegionFactory.setCache(gemfireCache);
|
||||
exampleRegionFactory.setClose(false);
|
||||
exampleRegionFactory.setShortcut(ClientRegionShortcut.PROXY);
|
||||
|
||||
return exampleRegionFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
BeanPostProcessor gemfireClientServerReadyBeanPostProcessor(
|
||||
@Value("${spring-session-data-gemfire.cache.server.host:localhost}") final String host,
|
||||
@Value("${spring-session-data-gemfire.cache.server.port:40404}") final int port) { // <5>
|
||||
|
||||
return new BeanPostProcessor() {
|
||||
|
||||
private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true);
|
||||
private final AtomicReference<Pool> defaultPool = new AtomicReference<>(null);
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) {
|
||||
try {
|
||||
validateCacheClientNotified();
|
||||
validateCacheClientSubscriptionQueueConnectionEstablished();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) {
|
||||
|
||||
return (isGemFireRegion(bean, beanName)
|
||||
? checkGemFireServerIsRunning.compareAndSet(true, false)
|
||||
: whenGemFireCache(bean, beanName));
|
||||
}
|
||||
|
||||
private boolean isGemFireRegion(Object bean, String beanName) {
|
||||
|
||||
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
|
||||
|| bean instanceof Region);
|
||||
}
|
||||
|
||||
private boolean whenGemFireCache(Object bean, String beanName) {
|
||||
|
||||
if (bean instanceof ClientCache) {
|
||||
defaultPool.compareAndSet(null, ((ClientCache) bean).getDefaultPool());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void validateCacheClientNotified() throws InterruptedException {
|
||||
|
||||
boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
|
||||
Assert.state(didNotTimeout, String.format(
|
||||
"GemFire Cache Server failed to start on host [%s] and port [%d]", host, port));
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException {
|
||||
|
||||
boolean cacheClientSubscriptionQueueConnectionEstablished = false;
|
||||
|
||||
Pool pool = defaultIfNull(this.defaultPool.get(), GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME,
|
||||
GEMFIRE_DEFAULT_POOL_NAME);
|
||||
|
||||
if (pool instanceof PoolImpl) {
|
||||
|
||||
long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT);
|
||||
|
||||
while (System.currentTimeMillis() < timeout
|
||||
&& !((PoolImpl) pool).isPrimaryUpdaterAlive()) {
|
||||
|
||||
synchronized (pool) {
|
||||
TimeUnit.MILLISECONDS.timedWait(pool, 500L);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cacheClientSubscriptionQueueConnectionEstablished |=
|
||||
((PoolImpl) pool).isPrimaryUpdaterAlive();
|
||||
}
|
||||
|
||||
Assert.state(cacheClientSubscriptionQueueConnectionEstablished, String.format(
|
||||
"Cache client subscription queue connection not established; GemFire Pool was [%s];"
|
||||
+ " GemFire Pool configuration was [locators = %s, servers = %s]",
|
||||
pool, pool.getLocators(), pool.getServers()));
|
||||
}
|
||||
|
||||
private Pool defaultIfNull(Pool pool, String... poolNames) {
|
||||
|
||||
AtomicReference<Pool> poolRef = new AtomicReference<>(null);
|
||||
|
||||
stream(nullSafeArray(poolNames, String.class)).forEach(poolName ->
|
||||
poolRef.set(Optional.ofNullable(pool).orElseGet(() -> PoolManager.find(poolName))));
|
||||
|
||||
return poolRef.get();
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
};
|
||||
return (beanName, cacheServerFactoryBean) ->
|
||||
cacheServerFactoryBean.setServers(Collections.singletonList(
|
||||
newConnectionEndpoint("localhost", port)));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class SpringWebMvcConfiguration {
|
||||
static class SpringWebMvcConfiguration { // <6>
|
||||
|
||||
@Bean
|
||||
public WebMvcConfigurer webMvcConfig() { // <6>
|
||||
public WebMvcConfigurer webMvcConfig() {
|
||||
|
||||
return new WebMvcConfigurer() {
|
||||
|
||||
@@ -310,9 +111,6 @@ public class Application {
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
private ClientCache gemfireCache;
|
||||
|
||||
@ExceptionHandler
|
||||
@ResponseBody
|
||||
public String errorHandler(Throwable error) {
|
||||
@@ -323,35 +121,22 @@ public class Application {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, path = "/ping")
|
||||
@ResponseBody
|
||||
public String ping() { // <7>
|
||||
public String ping() {
|
||||
return PING_RESPONSE;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, path = "/time")
|
||||
@ResponseBody
|
||||
public String time() {
|
||||
return String.valueOf(this.gemfireCache.getRegion("/Example").get("time"));
|
||||
}
|
||||
|
||||
/*
|
||||
@RequestMapping("/")
|
||||
public String index() { // <6>
|
||||
return INDEX_TEMPLATE_VIEW_NAME;
|
||||
}
|
||||
*/
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, path = "/session")
|
||||
public String session(HttpSession session, ModelMap modelMap,
|
||||
@RequestParam(name = "attributeName", required = false) String name,
|
||||
@RequestParam(name = "attributeValue", required = false) String value) { // <8>
|
||||
@RequestParam(name = "attributeValue", required = false) String value) { // <7>
|
||||
|
||||
modelMap.addAttribute("sessionAttributes", attributes(setAttribute(updateRequestCount(session), name, value)));
|
||||
modelMap.addAttribute("sessionAttributes",
|
||||
attributes(setAttribute(updateRequestCount(session), name, value)));
|
||||
|
||||
return INDEX_TEMPLATE_VIEW_NAME;
|
||||
}
|
||||
// end::class[]
|
||||
// end::class[]
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
HttpSession updateRequestCount(HttpSession session) {
|
||||
|
||||
@@ -362,17 +147,14 @@ public class Application {
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
Integer nullSafeIncrement(Integer value) {
|
||||
return (nullSafeIntValue(value) + 1);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
int nullSafeIntValue(Number value) {
|
||||
return Optional.ofNullable(value).map(Number::intValue).orElse(0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
HttpSession setAttribute(HttpSession session, String attributeName, String attributeValue) {
|
||||
|
||||
if (isSet(attributeName, attributeValue)) {
|
||||
@@ -382,7 +164,6 @@ public class Application {
|
||||
return session;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
boolean isSet(String... values) {
|
||||
|
||||
boolean set = true;
|
||||
@@ -394,7 +175,6 @@ public class Application {
|
||||
return set;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
Map<String, String> attributes(HttpSession session) {
|
||||
|
||||
Map<String, String> sessionAttributes = new HashMap<>();
|
||||
@@ -406,7 +186,6 @@ public class Application {
|
||||
return sessionAttributes;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
<T> Iterable<T> toIterable(Enumeration<T> enumeration) {
|
||||
|
||||
return () -> Optional.ofNullable(enumeration).map(CollectionUtils::toIterator)
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2017 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.client;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.apache.geode.cache.client.internal.PoolImpl;
|
||||
import org.apache.geode.management.membership.ClientMembership;
|
||||
import org.apache.geode.management.membership.ClientMembershipEvent;
|
||||
import org.apache.geode.management.membership.ClientMembershipListenerAdapter;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.support.ConnectionEndpoint;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The IntegrationTestConfiguration class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class IntegrationTestConfiguration {
|
||||
|
||||
static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(60);
|
||||
|
||||
static final CountDownLatch LATCH = new CountDownLatch(1);
|
||||
|
||||
static final String GEMFIRE_DEFAULT_POOL_NAME = "DEFAULT";
|
||||
|
||||
@Bean
|
||||
BeanPostProcessor clientServerReadyBeanPostProcessor(
|
||||
@Value("${spring.session.data.geode.cache.server.port:40404}") int port) { // <5>
|
||||
|
||||
return new BeanPostProcessor() {
|
||||
|
||||
private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true);
|
||||
private final AtomicReference<Pool> defaultPool = new AtomicReference<>(null);
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) {
|
||||
try {
|
||||
validateCacheClientNotified();
|
||||
validateCacheClientSubscriptionQueueConnectionEstablished();
|
||||
}
|
||||
catch (InterruptedException cause) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) {
|
||||
|
||||
return (isGemFireRegion(bean, beanName)
|
||||
? checkGemFireServerIsRunning.compareAndSet(true, false)
|
||||
: whenGemFireCache(bean, beanName));
|
||||
}
|
||||
|
||||
private boolean isGemFireRegion(Object bean, String beanName) {
|
||||
|
||||
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
|
||||
|| bean instanceof Region);
|
||||
}
|
||||
|
||||
private boolean whenGemFireCache(Object bean, String beanName) {
|
||||
|
||||
if (bean instanceof ClientCache) {
|
||||
defaultPool.compareAndSet(null, ((ClientCache) bean).getDefaultPool());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void validateCacheClientNotified() throws InterruptedException {
|
||||
|
||||
boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
|
||||
Assert.state(didNotTimeout, String.format(
|
||||
"Apache Geode Cache Server failed to start on host [%s] and port [%d]", "localhost", port));
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException {
|
||||
|
||||
boolean cacheClientSubscriptionQueueConnectionEstablished = false;
|
||||
|
||||
Pool pool = defaultIfNull(this.defaultPool.get(), GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME,
|
||||
GEMFIRE_DEFAULT_POOL_NAME);
|
||||
|
||||
if (pool instanceof PoolImpl) {
|
||||
|
||||
long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT);
|
||||
|
||||
while (System.currentTimeMillis() < timeout && !((PoolImpl) pool).isPrimaryUpdaterAlive()) {
|
||||
synchronized (pool) {
|
||||
TimeUnit.MILLISECONDS.timedWait(pool, 500L);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cacheClientSubscriptionQueueConnectionEstablished |= ((PoolImpl) pool).isPrimaryUpdaterAlive();
|
||||
}
|
||||
|
||||
Assert.state(cacheClientSubscriptionQueueConnectionEstablished,
|
||||
String.format("Cache client subscription queue connection not established; Geode Pool was [%s];"
|
||||
+ " Geode Pool configuration was [locators = %s, servers = %s]",
|
||||
pool, pool.getLocators(), pool.getServers()));
|
||||
}
|
||||
|
||||
private Pool defaultIfNull(Pool pool, String... poolNames) {
|
||||
|
||||
for (String poolName : poolNames) {
|
||||
pool = (pool != null ? pool : PoolManager.find(poolName));
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ConnectionEndpoint newConnectionEndpoint(String host, int port) {
|
||||
return new ConnectionEndpoint(host, port);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientCacheConfigurer registerClientMembershipListener() {
|
||||
|
||||
return (beanName, bean) -> {
|
||||
|
||||
ClientMembership.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void memberJoined(ClientMembershipEvent event) {
|
||||
LATCH.countDown();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -16,27 +16,15 @@
|
||||
|
||||
package sample.server;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerConfigurer;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableManager;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
|
||||
/**
|
||||
@@ -51,103 +39,31 @@ import org.springframework.session.data.gemfire.config.annotation.web.http.Enabl
|
||||
* @since 1.2.1
|
||||
*/
|
||||
// tag::class[]
|
||||
@SpringBootApplication
|
||||
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 20) // <1>
|
||||
@SpringBootApplication // <1>
|
||||
@CacheServerApplication(name = "SpringSessionDataGeodeServerBootSample", logLevel = "warning") // <2>
|
||||
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 20) // <3>
|
||||
@EnableManager(start = true) // <4>
|
||||
@SuppressWarnings("unused")
|
||||
public class GemFireServer {
|
||||
|
||||
static final String DEFAULT_GEMFIRE_LOG_LEVEL = "config";
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication springApplication = new SpringApplication(GemFireServer.class);
|
||||
springApplication.setWebApplicationType(WebApplicationType.NONE);
|
||||
springApplication.run(args);
|
||||
}
|
||||
|
||||
// Required to resolve property placeholders in Spring @Value annotations.
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() { // <2>
|
||||
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", applicationName());
|
||||
//gemfireProperties.setProperty("log-file", "gemfire-server.log");
|
||||
gemfireProperties.setProperty("log-level", logLevel());
|
||||
gemfireProperties.setProperty("jmx-manager", "true");
|
||||
gemfireProperties.setProperty("jmx-manager-start", "true");
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
String applicationName() {
|
||||
return "spring-session-data-gemfire-boot-sample:".concat(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
String logLevel() {
|
||||
return System.getProperty("spring-session-data-gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL);
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheFactoryBean gemfireCache() { // <3>
|
||||
CacheServerConfigurer cacheServerPortConfigurer(
|
||||
@Value("${spring.session.data.geode.cache.server.port:40404}") int port) { // <5>
|
||||
|
||||
CacheFactoryBean gemfireCache = new CacheFactoryBean();
|
||||
|
||||
gemfireCache.setClose(true);
|
||||
gemfireCache.setProperties(gemfireProperties());
|
||||
|
||||
return gemfireCache;
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheServerFactoryBean gemfireCacheServer(GemFireCache gemfireCache,
|
||||
@Value("${spring-session-data-gemfire.cache.server.bind-address:localhost}") String bindAddress,
|
||||
@Value("${spring-session-data-gemfire.cache.server.hostname-for-clients:localhost}") String hostnameForClients,
|
||||
@Value("${spring-session-data-gemfire.cache.server.port:40404}") int port) { // <4>
|
||||
|
||||
CacheServerFactoryBean gemfireCacheServer = new CacheServerFactoryBean();
|
||||
|
||||
gemfireCacheServer.setAutoStartup(true);
|
||||
gemfireCacheServer.setBindAddress(bindAddress);
|
||||
gemfireCacheServer.setCache((Cache) gemfireCache);
|
||||
gemfireCacheServer.setHostNameForClients(hostnameForClients);
|
||||
gemfireCacheServer.setMaxTimeBetweenPings(Long.valueOf(TimeUnit.SECONDS.toMillis(60)).intValue());
|
||||
gemfireCacheServer.setPort(port);
|
||||
|
||||
return gemfireCacheServer;
|
||||
}
|
||||
|
||||
@Bean(name = "Example")
|
||||
@Profile("debug")
|
||||
ReplicatedRegionFactoryBean<String, Object> exampleRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ReplicatedRegionFactoryBean<String, Object> exampleRegionFactory = new ReplicatedRegionFactoryBean<>();
|
||||
|
||||
exampleRegionFactory.setCache(gemfireCache);
|
||||
exampleRegionFactory.setClose(false);
|
||||
|
||||
return exampleRegionFactory;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private GemFireCache gemfireCache;
|
||||
|
||||
@Bean
|
||||
@Profile("debug")
|
||||
CommandLineRunner exampleInitializer() {
|
||||
|
||||
return args -> {
|
||||
|
||||
Region<String, Object> example = this.gemfireCache.getRegion("/Example");
|
||||
|
||||
String key = "time";
|
||||
|
||||
example.put(key, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:ss a")));
|
||||
|
||||
System.err.printf("Example.get(%s) is [%s]%n", key, example.get(key));
|
||||
};
|
||||
return (beanName, cacheServerFactoryBean) ->
|
||||
cacheServerFactoryBean.setPort(port);
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
|
||||
@@ -76,6 +76,7 @@ public final class NativeGemFireServer implements Runnable {
|
||||
}
|
||||
|
||||
private static void writeStringTo(File file, String fileContents) {
|
||||
|
||||
PrintWriter fileWriter = null;
|
||||
|
||||
try {
|
||||
@@ -92,6 +93,7 @@ public final class NativeGemFireServer implements Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NativeGemFireServer(String[] args) {
|
||||
this.args = nullSafeStringArray(args);
|
||||
}
|
||||
@@ -122,11 +124,13 @@ public final class NativeGemFireServer implements Runnable {
|
||||
}
|
||||
|
||||
private String applicationName(String applicationName) {
|
||||
|
||||
return StringUtils.hasText(applicationName) ? applicationName
|
||||
: "spring-session-data-gemfire.boot.sample." + NativeGemFireServer.class.getSimpleName();
|
||||
}
|
||||
|
||||
private Properties gemfireProperties(String applicationName) {
|
||||
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", applicationName);
|
||||
@@ -143,6 +147,7 @@ public final class NativeGemFireServer implements Runnable {
|
||||
}
|
||||
|
||||
private Cache createRegion(Cache gemfireCache) {
|
||||
|
||||
RegionFactory<Object, AbstractGemFireOperationsSessionRepository.GemFireSession> regionFactory =
|
||||
gemfireCache.createRegionFactory(RegionShortcut.PARTITION);
|
||||
|
||||
@@ -162,6 +167,7 @@ public final class NativeGemFireServer implements Runnable {
|
||||
}
|
||||
|
||||
private Cache addCacheServer(Cache gemfireCache) throws IOException {
|
||||
|
||||
CacheServer cacheServer = gemfireCache.addCacheServer();
|
||||
|
||||
cacheServer.setBindAddress(GEMFIRE_CACHE_SERVER_HOST);
|
||||
@@ -173,6 +179,7 @@ public final class NativeGemFireServer implements Runnable {
|
||||
}
|
||||
|
||||
private Cache registerShutdownHook(final Cache gemfireCache) {
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
||||
public void run() {
|
||||
if (gemfireCache != null) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
apply plugin: 'io.spring.convention.spring-sample-war'
|
||||
apply plugin: "gemfire-server"
|
||||
apply plugin: "application"
|
||||
|
||||
apply from: IDE_GRADLE
|
||||
|
||||
@@ -25,3 +26,5 @@ dependencies {
|
||||
integrationTestRuntime "org.springframework.shell:spring-shell"
|
||||
|
||||
}
|
||||
|
||||
mainClassName = "sample.ServerConfig"
|
||||
|
||||
@@ -17,200 +17,33 @@
|
||||
package sample;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.apache.geode.cache.client.internal.PoolImpl;
|
||||
import org.apache.geode.management.membership.ClientMembership;
|
||||
import org.apache.geode.management.membership.ClientMembershipEvent;
|
||||
import org.apache.geode.management.membership.ClientMembershipListenerAdapter;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.support.ConnectionEndpoint;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
// tag::class[]
|
||||
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30, poolName = "DEFAULT") // <1>
|
||||
public class ClientConfig {
|
||||
|
||||
static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(60);
|
||||
|
||||
static final CountDownLatch LATCH = new CountDownLatch(1);
|
||||
|
||||
static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning";
|
||||
static final String GEMFIRE_DEFAULT_POOL_NAME = "DEFAULT";
|
||||
static final String PROXY_HOST = "dummy.example.com";
|
||||
static final String PROXY_PORT = "3128";
|
||||
@ClientCacheApplication(name = "SpringSessionDataGeodeClientJavaConfigSample", logLevel = "warning",
|
||||
pingInterval = 5000L, readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true) // <1>
|
||||
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30, poolName = "DEFAULT") // <2>
|
||||
public class ClientConfig extends IntegrationTestConfig {
|
||||
|
||||
// Required to resolve property placeholders in Spring @Value annotations.
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() { // <2>
|
||||
Properties gemfireProperties = new Properties();
|
||||
gemfireProperties.setProperty("name", applicationName());
|
||||
// gemfireProperties.setProperty("log-file", "gemfire-client.log");
|
||||
gemfireProperties.setProperty("log-level", logLevel());
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
String applicationName() {
|
||||
return "spring-session-data-gemfire-clientserver-javaconfig-sample:".concat(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
String logLevel() {
|
||||
return System.getProperty("spring.session.data.gemfire.log-level", DEFAULT_GEMFIRE_LOG_LEVEL);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientCacheFactoryBean gemfireCache(
|
||||
@Value("${spring.session.data.gemfire.host:" + ServerConfig.SERVER_HOST + "}") String host,
|
||||
@Value("${spring.session.data.gemfire.port:" + ServerConfig.SERVER_PORT + "}") int port) { // <3>
|
||||
ClientCacheConfigurer clientCacheServerPortConfigurer(
|
||||
@Value("${spring.session.data.geode.cache.server.port:40404}") int port) { // <3>
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean();
|
||||
|
||||
clientCacheFactory.setClose(true);
|
||||
clientCacheFactory.setProperties(gemfireProperties());
|
||||
|
||||
// GemFire Pool settings <4>
|
||||
clientCacheFactory.setKeepAlive(false);
|
||||
clientCacheFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5));
|
||||
clientCacheFactory.setReadTimeout(intValue(TimeUnit.SECONDS.toMillis(15)));
|
||||
clientCacheFactory.setRetryAttempts(1);
|
||||
clientCacheFactory.setSubscriptionEnabled(true);
|
||||
clientCacheFactory.setThreadLocalConnections(false);
|
||||
clientCacheFactory.setServers(Collections.singletonList(newConnectionEndpoint(host, port)));
|
||||
|
||||
registerClientMembershipListener(); // <5>
|
||||
|
||||
return clientCacheFactory;
|
||||
return (beanName, clientCacheFactoryBean) ->
|
||||
clientCacheFactoryBean.setServers(Collections.singletonList(
|
||||
newConnectionEndpoint("localhost", port)));
|
||||
}
|
||||
|
||||
int intValue(Number number) {
|
||||
return number.intValue();
|
||||
}
|
||||
|
||||
ConnectionEndpoint newConnectionEndpoint(String host, int port) {
|
||||
return new ConnectionEndpoint(host, port);
|
||||
}
|
||||
|
||||
void registerClientMembershipListener() {
|
||||
ClientMembership.registerClientMembershipListener(
|
||||
new ClientMembershipListenerAdapter() {
|
||||
@Override
|
||||
public void memberJoined(ClientMembershipEvent event) {
|
||||
LATCH.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
BeanPostProcessor gemfireClientServerReadyBeanPostProcessor(
|
||||
@Value("${spring-session-data-gemfire.cache.server.host:localhost}") final String host,
|
||||
@Value("${spring-session-data-gemfire.cache.server.port:12480}") final int port) { // <5>
|
||||
|
||||
return new BeanPostProcessor() {
|
||||
|
||||
private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true);
|
||||
private final AtomicReference<Pool> defaultPool = new AtomicReference<Pool>(null);
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) {
|
||||
try {
|
||||
validateCacheClientNotified();
|
||||
validateCacheClientSubscriptionQueueConnectionEstablished();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) {
|
||||
return (isGemFireRegion(bean, beanName)
|
||||
? checkGemFireServerIsRunning.compareAndSet(true, false)
|
||||
: whenGemFireCache(bean, beanName));
|
||||
}
|
||||
|
||||
private boolean isGemFireRegion(Object bean, String beanName) {
|
||||
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
|
||||
|| bean instanceof Region);
|
||||
}
|
||||
|
||||
private boolean whenGemFireCache(Object bean, String beanName) {
|
||||
if (bean instanceof ClientCache) {
|
||||
defaultPool.compareAndSet(null, ((ClientCache) bean).getDefaultPool());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void validateCacheClientNotified() throws InterruptedException {
|
||||
boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
|
||||
Assert.state(didNotTimeout, String.format(
|
||||
"GemFire Cache Server failed to start on host [%s] and port [%d]", host, port));
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException {
|
||||
boolean cacheClientSubscriptionQueueConnectionEstablished = false;
|
||||
|
||||
Pool pool = defaultIfNull(this.defaultPool.get(), GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME,
|
||||
GEMFIRE_DEFAULT_POOL_NAME);
|
||||
|
||||
if (pool instanceof PoolImpl) {
|
||||
long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT);
|
||||
|
||||
while (System.currentTimeMillis() < timeout
|
||||
&& !((PoolImpl) pool).isPrimaryUpdaterAlive()) {
|
||||
|
||||
synchronized (pool) {
|
||||
TimeUnit.MILLISECONDS.timedWait(pool, 500L);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cacheClientSubscriptionQueueConnectionEstablished |=
|
||||
((PoolImpl) pool).isPrimaryUpdaterAlive();
|
||||
}
|
||||
|
||||
Assert.state(cacheClientSubscriptionQueueConnectionEstablished, String.format(
|
||||
"Cache client subscription queue connection not established; GemFire Pool was [%s];"
|
||||
+ " GemFire Pool configuration was [locators = %s, servers = %s]",
|
||||
pool, pool.getLocators(), pool.getServers()));
|
||||
}
|
||||
|
||||
private Pool defaultIfNull(Pool pool, String... poolNames) {
|
||||
for (String poolName : poolNames) {
|
||||
pool = (pool != null ? pool : PoolManager.find(poolName));
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
};
|
||||
}
|
||||
// end::class[]
|
||||
}
|
||||
// end::class[]
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2017 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.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.apache.geode.cache.client.internal.PoolImpl;
|
||||
import org.apache.geode.management.membership.ClientMembership;
|
||||
import org.apache.geode.management.membership.ClientMembershipEvent;
|
||||
import org.apache.geode.management.membership.ClientMembershipListenerAdapter;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.support.ConnectionEndpoint;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The IntegrationTestConfig class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public abstract class IntegrationTestConfig {
|
||||
|
||||
static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(60);
|
||||
|
||||
static final CountDownLatch LATCH = new CountDownLatch(1);
|
||||
|
||||
static final String GEMFIRE_DEFAULT_POOL_NAME = "DEFAULT";
|
||||
|
||||
@Bean
|
||||
BeanPostProcessor clientServerReadyBeanPostProcessor(
|
||||
@Value("${spring.session.data.geode.cache.server.port:40404}") int port) { // <5>
|
||||
|
||||
return new BeanPostProcessor() {
|
||||
|
||||
private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true);
|
||||
private final AtomicReference<Pool> defaultPool = new AtomicReference<>(null);
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) {
|
||||
try {
|
||||
validateCacheClientNotified();
|
||||
validateCacheClientSubscriptionQueueConnectionEstablished();
|
||||
}
|
||||
catch (InterruptedException cause) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) {
|
||||
|
||||
return (isGemFireRegion(bean, beanName)
|
||||
? checkGemFireServerIsRunning.compareAndSet(true, false)
|
||||
: whenGemFireCache(bean, beanName));
|
||||
}
|
||||
|
||||
private boolean isGemFireRegion(Object bean, String beanName) {
|
||||
|
||||
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
|
||||
|| bean instanceof Region);
|
||||
}
|
||||
|
||||
private boolean whenGemFireCache(Object bean, String beanName) {
|
||||
|
||||
if (bean instanceof ClientCache) {
|
||||
defaultPool.compareAndSet(null, ((ClientCache) bean).getDefaultPool());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void validateCacheClientNotified() throws InterruptedException {
|
||||
|
||||
boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
|
||||
Assert.state(didNotTimeout, String.format(
|
||||
"Apache Geode Cache Server failed to start on host [%s] and port [%d]", "localhost", port));
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException {
|
||||
|
||||
boolean cacheClientSubscriptionQueueConnectionEstablished = false;
|
||||
|
||||
Pool pool = defaultIfNull(this.defaultPool.get(), GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME,
|
||||
GEMFIRE_DEFAULT_POOL_NAME);
|
||||
|
||||
if (pool instanceof PoolImpl) {
|
||||
|
||||
long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT);
|
||||
|
||||
while (System.currentTimeMillis() < timeout && !((PoolImpl) pool).isPrimaryUpdaterAlive()) {
|
||||
synchronized (pool) {
|
||||
TimeUnit.MILLISECONDS.timedWait(pool, 500L);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cacheClientSubscriptionQueueConnectionEstablished |= ((PoolImpl) pool).isPrimaryUpdaterAlive();
|
||||
}
|
||||
|
||||
Assert.state(cacheClientSubscriptionQueueConnectionEstablished,
|
||||
String.format("Cache client subscription queue connection not established; Geode Pool was [%s];"
|
||||
+ " Geode Pool configuration was [locators = %s, servers = %s]",
|
||||
pool, pool.getLocators(), pool.getServers()));
|
||||
}
|
||||
|
||||
private Pool defaultIfNull(Pool pool, String... poolNames) {
|
||||
|
||||
for (String poolName : poolNames) {
|
||||
pool = (pool != null ? pool : PoolManager.find(poolName));
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ConnectionEndpoint newConnectionEndpoint(String host, int port) {
|
||||
return new ConnectionEndpoint(host, port);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientCacheConfigurer registerClientMembershipListener() {
|
||||
|
||||
return (beanName, bean) -> {
|
||||
|
||||
ClientMembership.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void memberJoined(ClientMembershipEvent event) {
|
||||
LATCH.countDown();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -17,86 +17,38 @@
|
||||
package sample;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
|
||||
import org.springframework.data.gemfire.config.annotation.CacheServerConfigurer;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
|
||||
// tag::class[]
|
||||
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) // <1>
|
||||
@CacheServerApplication(name = "SpringSessionSampleJavaConfigGemFireClientServer", logLevel = "warning") // <1>
|
||||
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) // <2>
|
||||
public class ServerConfig {
|
||||
|
||||
static final int SERVER_PORT = 12480;
|
||||
|
||||
static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning";
|
||||
static final String SERVER_HOST = "localhost";
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public static void main(String[] args) throws IOException { // <5>
|
||||
public static void main(String[] args) throws IOException {
|
||||
new AnnotationConfigApplicationContext(ServerConfig.class).registerShutdownHook();
|
||||
}
|
||||
|
||||
// Required to resolve property placeholders in Spring @Value annotations.
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
Properties gemfireProperties() { // <2>
|
||||
|
||||
Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", applicationName());
|
||||
gemfireProperties.setProperty("mcast-port", "0");
|
||||
// gemfireProperties.setProperty("log-file", "gemfire-server.log");
|
||||
gemfireProperties.setProperty("log-level", logLevel());
|
||||
// gemfireProperties.setProperty("jmx-manager", "true");
|
||||
// gemfireProperties.setProperty("jmx-manager-start", "true");
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
String applicationName() {
|
||||
return "samples:httpsession-gemfire-clientserver:".concat(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
String logLevel() {
|
||||
return System.getProperty("sample.httpsession.gemfire.log-level", DEFAULT_GEMFIRE_LOG_LEVEL);
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheFactoryBean gemfireCache() { // <3>
|
||||
CacheServerConfigurer cacheServerPortConfigurer(
|
||||
@Value("${spring.session.data.geode.cache.server.port:40404}") int port) { // <3>
|
||||
|
||||
CacheFactoryBean gemfireCache = new CacheFactoryBean();
|
||||
|
||||
gemfireCache.setClose(true);
|
||||
gemfireCache.setProperties(gemfireProperties());
|
||||
|
||||
return gemfireCache;
|
||||
}
|
||||
|
||||
@Bean
|
||||
CacheServerFactoryBean gemfireCacheServer(GemFireCache gemfireCache,
|
||||
@Value("${spring.session.data.gemfire.port:" + SERVER_PORT + "}") int port) { // <4>
|
||||
|
||||
CacheServerFactoryBean gemfireCacheServer = new CacheServerFactoryBean();
|
||||
|
||||
gemfireCacheServer.setAutoStartup(true);
|
||||
gemfireCacheServer.setBindAddress(SERVER_HOST);
|
||||
gemfireCacheServer.setCache((Cache) gemfireCache);
|
||||
gemfireCacheServer.setHostNameForClients(SERVER_HOST);
|
||||
gemfireCacheServer.setMaxTimeBetweenPings(Long.valueOf(TimeUnit.SECONDS.toMillis(60)).intValue());
|
||||
gemfireCacheServer.setPort(port);
|
||||
|
||||
return gemfireCacheServer;
|
||||
return (beanName, cacheServerFactoryBean) -> {
|
||||
cacheServerFactoryBean.setPort(port);
|
||||
};
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
|
||||
@@ -28,15 +28,17 @@ import javax.servlet.http.HttpServletResponse;
|
||||
@WebServlet("/session")
|
||||
public class SessionServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 2878267318695777395L;
|
||||
|
||||
@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[]
|
||||
|
||||
@@ -16,38 +16,15 @@
|
||||
|
||||
package sample;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.EnableManager;
|
||||
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
|
||||
|
||||
// tag::class[]
|
||||
@EnableGemFireHttpSession // <1>
|
||||
@PeerCacheApplication(name = "SpringSessionSampleJavaConfigGemFireP2p", logLevel = "warning") // <1>
|
||||
@EnableGemFireHttpSession // <2>
|
||||
@EnableManager(start = true) // <3>
|
||||
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.setClose(true);
|
||||
gemfireCache.setProperties(gemfireProperties());
|
||||
|
||||
return gemfireCache;
|
||||
}
|
||||
}
|
||||
// end::class[]
|
||||
|
||||
@@ -28,15 +28,17 @@ import javax.servlet.http.HttpServletResponse;
|
||||
@WebServlet("/session")
|
||||
public class SessionServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 2878267318695777395L;
|
||||
|
||||
@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[]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
apply plugin: 'io.spring.convention.spring-sample-war'
|
||||
apply plugin: "gemfire-server"
|
||||
apply plugin: "application"
|
||||
|
||||
apply from: IDE_GRADLE
|
||||
|
||||
@@ -25,3 +26,5 @@ dependencies {
|
||||
integrationTestRuntime "org.springframework.shell:spring-shell"
|
||||
|
||||
}
|
||||
|
||||
mainClassName = "sample.ServerConfig"
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class GemFireClientServerReadyBeanPostProcessor implements BeanPostProcessor {
|
||||
public class ClientServerReadyBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(60);
|
||||
|
||||
@@ -55,16 +55,17 @@ public class GemFireClientServerReadyBeanPostProcessor implements BeanPostProces
|
||||
);
|
||||
}
|
||||
|
||||
@Value("${spring.session.data.gemfire.port:${application.gemfire.client-server.port}}")
|
||||
@Value("${spring.session.data.geode.cache.server.port:${application.geode.client-server.port:40404}}")
|
||||
private int port;
|
||||
|
||||
@Value("${application.gemfire.client-server.host:localhost}")
|
||||
@Value("${application.geode.client-server.host:localhost}")
|
||||
private String host;
|
||||
|
||||
private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true);
|
||||
private final AtomicReference<Pool> gemfirePool = new AtomicReference<Pool>(null);
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) {
|
||||
try {
|
||||
validateCacheClientNotified();
|
||||
@@ -79,17 +80,20 @@ public class GemFireClientServerReadyBeanPostProcessor implements BeanPostProces
|
||||
}
|
||||
|
||||
private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) {
|
||||
|
||||
return (isGemFireRegion(bean, beanName)
|
||||
? this.checkGemFireServerIsRunning.compareAndSet(true, false)
|
||||
: whenGemFirePool(bean, beanName));
|
||||
}
|
||||
|
||||
private boolean isGemFireRegion(Object bean, String beanName) {
|
||||
|
||||
return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName)
|
||||
|| bean instanceof Region);
|
||||
}
|
||||
|
||||
private boolean whenGemFirePool(Object bean, String beanName) {
|
||||
|
||||
if (bean instanceof Pool) {
|
||||
this.gemfirePool.compareAndSet(null, (Pool) bean);
|
||||
}
|
||||
@@ -98,24 +102,26 @@ public class GemFireClientServerReadyBeanPostProcessor implements BeanPostProces
|
||||
}
|
||||
|
||||
private void validateCacheClientNotified() throws InterruptedException {
|
||||
|
||||
boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
|
||||
Assert.state(didNotTimeout, String.format(
|
||||
"GemFire Cache Server failed to start on host [%s] and port [%d]", this.host, this.port));
|
||||
"Apache Geode Cache Server failed to start on host [%s] and port [%d]", this.host, this.port));
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException {
|
||||
|
||||
boolean cacheClientSubscriptionQueueConnectionEstablished = false;
|
||||
|
||||
Pool pool = defaultIfNull(this.gemfirePool.get(),
|
||||
GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, GEMFIRE_DEFAULT_POOL_NAME);
|
||||
|
||||
if (pool instanceof PoolImpl) {
|
||||
|
||||
long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT);
|
||||
|
||||
while (System.currentTimeMillis() < timeout
|
||||
&& !((PoolImpl) pool).isPrimaryUpdaterAlive()) {
|
||||
while (System.currentTimeMillis() < timeout && !((PoolImpl) pool).isPrimaryUpdaterAlive()) {
|
||||
|
||||
synchronized (pool) {
|
||||
TimeUnit.MILLISECONDS.timedWait(pool, 500L);
|
||||
@@ -127,13 +133,14 @@ public class GemFireClientServerReadyBeanPostProcessor implements BeanPostProces
|
||||
((PoolImpl) pool).isPrimaryUpdaterAlive();
|
||||
}
|
||||
|
||||
Assert.state(cacheClientSubscriptionQueueConnectionEstablished, String.format(
|
||||
"Cache client subscription queue connection not established; GemFire Pool was [%s];"
|
||||
+ " GemFire Pool configuration was [locators = %s, servers = %s]",
|
||||
Assert.state(cacheClientSubscriptionQueueConnectionEstablished,
|
||||
String.format("Cache client subscription queue connection not established; Geode Pool was [%s];"
|
||||
+ " Geode Pool configuration was [locators = %s, servers = %s]",
|
||||
pool, pool.getLocators(), pool.getServers()));
|
||||
}
|
||||
|
||||
private Pool defaultIfNull(Pool pool, String... poolNames) {
|
||||
|
||||
for (String poolName : poolNames) {
|
||||
pool = (pool != null ? pool : PoolManager.find(poolName));
|
||||
}
|
||||
@@ -145,4 +152,3 @@ public class GemFireClientServerReadyBeanPostProcessor implements BeanPostProces
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
// tag::end[]
|
||||
@@ -20,7 +20,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
// tag::class[]
|
||||
@Configuration // <1>
|
||||
@ImportResource("META-INF/spring/session-server.xml") // <2>
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
application.gemfire.client-server.host=localhost
|
||||
application.gemfire.client-server.port=40404
|
||||
application.geode.client-server.host=localhost
|
||||
application.geode.client-server.port=40404
|
||||
|
||||
@@ -13,17 +13,13 @@
|
||||
">
|
||||
|
||||
<!-- tag::beans[] -->
|
||||
<!--1-->
|
||||
<context:annotation-config/>
|
||||
|
||||
<!--2-->
|
||||
<context:property-placeholder location="classpath:META-INF/spring/application.properties"/>
|
||||
|
||||
<!--3-->
|
||||
<!--1-->
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="name">GemFireClientServerHttpSessionXmlSample</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
<!--<prop key="log-file">gemfire-server.log</prop>-->
|
||||
<prop key="name">SpringSessionSampleXmlGemFireClientServer</prop>
|
||||
<prop key="log-level">${spring.session.data.gemfire.log-level:warning}</prop>
|
||||
<!--
|
||||
<prop key="jmx-manager">true</prop>
|
||||
@@ -31,16 +27,16 @@
|
||||
-->
|
||||
</util:properties>
|
||||
|
||||
<!--4-->
|
||||
<!--2-->
|
||||
<gfe:cache properties-ref="gemfireProperties"/>
|
||||
|
||||
<!--5-->
|
||||
<!--3-->
|
||||
<gfe:cache-server auto-startup="true"
|
||||
bind-address="${application.gemfire.client-server.host:localhost}"
|
||||
host-name-for-clients="${application.gemfire.client-server.host:localhost}"
|
||||
port="${spring.session.data.gemfire.port:${application.gemfire.client-server.port:40404}}"/>
|
||||
bind-address="${application.geode.client-server.host:localhost}"
|
||||
host-name-for-clients="${application.geode.client-server.host:localhost}"
|
||||
port="${spring.session.data.geode.cache.server.port:${application.geode.client-server.port:40404}}"/>
|
||||
|
||||
<!--6-->
|
||||
<!--4-->
|
||||
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
|
||||
p:maxInactiveIntervalInSeconds="30"/>
|
||||
<!-- end::beans[] -->
|
||||
|
||||
@@ -13,36 +13,27 @@
|
||||
">
|
||||
|
||||
<!-- tag::beans[] -->
|
||||
<!--1-->
|
||||
<context:annotation-config/>
|
||||
|
||||
<!--2-->
|
||||
<context:property-placeholder location="classpath:META-INF/spring/application.properties"/>
|
||||
|
||||
<!--3-->
|
||||
<bean class="sample.GemFireClientServerReadyBeanPostProcessor"/>
|
||||
<bean class="sample.ClientServerReadyBeanPostProcessor"/>
|
||||
|
||||
<!--4-->
|
||||
<!--1-->
|
||||
<util:properties id="gemfireProperties">
|
||||
<!--<prop key="log-file">gemfire-client.log</prop>-->
|
||||
<prop key="log-level">${spring.session.data.gemfire.log-level:warning}</prop>
|
||||
<prop key="log-level">${spring.session.data.geode.log-level:warning}</prop>
|
||||
</util:properties>
|
||||
|
||||
<!--5-->
|
||||
<!--2-->
|
||||
<gfe:client-cache properties-ref="gemfireProperties" pool-name="gemfirePool"/>
|
||||
|
||||
<!--6-->
|
||||
<gfe:pool keep-alive="false"
|
||||
ping-interval="5000"
|
||||
read-timeout="15000"
|
||||
retry-attempts="1"
|
||||
subscription-enabled="true"
|
||||
thread-local-connections="false">
|
||||
<gfe:server host="${application.gemfire.client-server.host}"
|
||||
port="${spring.session.data.gemfire.port:${application.gemfire.client-server.port}}"/>
|
||||
<!--3-->
|
||||
<gfe:pool ping-interval="5000" read-timeout="15000" retry-attempts="1" subscription-enabled="true">
|
||||
<gfe:server host="${application.geode.client-server.host}"
|
||||
port="${spring.session.data.geode.cache.server.port:${application.geode.client-server.port:40404}}"/>
|
||||
</gfe:pool>
|
||||
|
||||
<!--7-->
|
||||
<!--4-->
|
||||
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"
|
||||
p:maxInactiveIntervalInSeconds="30" p:poolName="DEFAULT"/>
|
||||
<!-- end::beans[] -->
|
||||
|
||||
@@ -26,15 +26,17 @@ import javax.servlet.http.HttpServletResponse;
|
||||
// tag::class[]
|
||||
public class SessionServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 2878267318695777395L;
|
||||
|
||||
@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;
|
||||
}
|
||||
// end::class[]
|
||||
|
||||
@@ -12,23 +12,23 @@
|
||||
">
|
||||
|
||||
<!-- tag::beans[] -->
|
||||
<!--1-->
|
||||
<context:annotation-config/>
|
||||
|
||||
<context:property-placeholder/>
|
||||
|
||||
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"/>
|
||||
|
||||
<!--2-->
|
||||
<!--1-->
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="name">GemFireP2PHttpSessionXmlSample</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
<prop key="log-level">${sample.httpsession.gemfire.log-level:warning}</prop>
|
||||
<prop key="name">SpringSessionSampleXmlGemFireP2p</prop>
|
||||
<prop key="log-level">${spring.session.data.geode.log-level:warning}</prop>
|
||||
<prop key="jmx-manager">true</prop>
|
||||
<prop key="jmx-manager-start">true</prop>
|
||||
</util:properties>
|
||||
|
||||
<!--3-->
|
||||
<!--2-->
|
||||
<gfe:cache properties-ref="gemfireProperties" use-bean-factory-locator="false"/>
|
||||
|
||||
<!--3-->
|
||||
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"/>
|
||||
<!-- end::beans[] -->
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user