Update to Spring Boot 1.4.1.RELEASE

* Upgrade to Spring Data GemFire 1.8.4.RELEASE
 * Upgrade to Spring Data MongoDB 1.9.4.RELEASE
 * Upgrade to Spring Framework 4.3.3.RELEASE

(Upgrade to Spring Data Redis 1.7.4.RELEASE failed)

Fixes gh-632
This commit is contained in:
John Blum
2016-09-17 12:46:32 -07:00
committed by Rob Winch
parent 7d680ff3ef
commit f0820c8038
24 changed files with 642 additions and 625 deletions

View File

@@ -16,8 +16,6 @@
package sample.client;
import java.io.IOException;
import java.net.Socket;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -26,7 +24,6 @@ import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.http.HttpSession;
@@ -34,8 +31,6 @@ import com.gemstone.gemfire.cache.client.Pool;
import com.gemstone.gemfire.management.membership.ClientMembership;
import com.gemstone.gemfire.management.membership.ClientMembershipEvent;
import com.gemstone.gemfire.management.membership.ClientMembershipListenerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
@@ -47,8 +42,8 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.client.PoolFactoryBean;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
import org.springframework.session.data.gemfire.support.GemFireUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
@@ -59,16 +54,14 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* A Spring Boot-based GemFire cache client web application that reveals the current state
* of the HTTP Session.
* A Spring Boot, GemFire cache client, web application that reveals the current state of the HTTP Session.
*
* @author John Blum
* @see javax.servlet.http.HttpSession
* @see org.springframework.boot.SpringApplication
* @see org.springframework.boot.autoconfigure.SpringBootApplication
* @see org.springframework.context.annotation.Bean
* @see org.springframework.session.data.gemfire.config.annotation.web.http.
* EnableGemFireHttpSession
* @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession
* @see org.springframework.stereotype.Controller
* @see com.gemstone.gemfire.cache.client.ClientCache
* @since 1.2.1
@@ -79,63 +72,42 @@ import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Application {
static final int MAX_CONNECTIONS = 50;
static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20);
static final long DEFAULT_WAIT_INTERVAL = 500L;
static final CountDownLatch latch = new CountDownLatch(1);
static final String DEFAULT_GEMFIRE_LOG_LEVEL = "config";
static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning";
static final String INDEX_TEMPLATE_VIEW_NAME = "index";
static final String PING_RESPONSE = "PONG";
static final String REQUEST_COUNT_ATTRIBUTE_NAME = "requestCount";
static { // <6>
ClientMembership
.registerClientMembershipListener(new ClientMembershipListenerAdapter() {
@Override
public void memberJoined(ClientMembershipEvent event) {
if (!event.isClient()) {
latch.countDown();
}
}
});
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Bean
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
String applicationName() {
return "samples:httpsession-gemfire-boot-"
.concat(Application.class.getSimpleName());
}
String gemfireLogLevel() {
return System.getProperty("gemfire.log-level", DEFAULT_GEMFIRE_LOG_LEVEL);
}
ConnectionEndpoint newConnectionEndpoint(String host, int port) {
return new ConnectionEndpoint(host, port);
}
Properties gemfireProperties() { // <2>
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", applicationName());
gemfireProperties.setProperty("log-level", gemfireLogLevel());
gemfireProperties.setProperty("log-level", logLevel());
return gemfireProperties;
}
String applicationName() {
return "samples:httpsession-gemfire-boot:"
.concat(getClass().getSimpleName());
}
String logLevel() {
return System.getProperty("gemfire.log-level", DEFAULT_GEMFIRE_LOG_LEVEL);
}
@Bean
ClientCacheFactoryBean gemfireCache() { // <3>
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
@@ -153,18 +125,23 @@ public class Application {
PoolFactoryBean gemfirePool = new PoolFactoryBean();
gemfirePool.setMaxConnections(MAX_CONNECTIONS);
gemfirePool.setPingInterval(TimeUnit.SECONDS.toMillis(15));
gemfirePool.setKeepAlive(false);
gemfirePool.setPingInterval(TimeUnit.SECONDS.toMillis(5));
gemfirePool.setReadTimeout(Long.valueOf(TimeUnit.SECONDS.toMillis(2)).intValue());
gemfirePool.setRetryAttempts(1);
gemfirePool.setSubscriptionEnabled(true);
gemfirePool.setServerEndpoints(
Collections.singleton(newConnectionEndpoint(host, port)));
gemfirePool.setThreadLocalConnections(false);
gemfirePool.setServers(Collections.singleton(newConnectionEndpoint(host, port)));
return gemfirePool;
}
ConnectionEndpoint newConnectionEndpoint(String host, int port) {
return new ConnectionEndpoint(host, port);
}
@Bean
BeanPostProcessor gemfireCacheServerAvailabilityBeanPostProcessor(
BeanPostProcessor gemfireCacheServerReadyBeanPostProcessor(
@Value("${gemfire.cache.server.host:localhost}") final String host,
@Value("${gemfire.cache.server.port:12480}") final int port) { // <5>
@@ -172,12 +149,15 @@ public class Application {
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
if (!waitForCacheServerToStart(host, port)) {
Application.this.logger.warn(
"No GemFire Cache Server found on [host: {}, port: {}]",
host, port);
}
if ("gemfirePool".equals(beanName)) {
ClientMembership.registerClientMembershipListener(
new ClientMembershipListenerAdapter() {
@Override
public void memberJoined(ClientMembershipEvent event) {
latch.countDown();
}
});
}
return bean;
@@ -185,13 +165,12 @@ public class Application {
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof PoolFactoryBean || bean instanceof Pool) {
if (bean instanceof Pool && "gemfirePool".equals(beanName)) {
try {
Assert.state(
latch.await(DEFAULT_WAIT_DURATION, TimeUnit.MILLISECONDS),
String.format(
"GemFire Cache Server failed to start on [host: %1$s, port: %2$d]",
host, port));
Assert.state(latch.await(DEFAULT_WAIT_DURATION, TimeUnit.MILLISECONDS),
String.format("GemFire Cache Server failed to start on host [%1$s] and port [%2$d]",
host, port));
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
@@ -204,23 +183,23 @@ public class Application {
}
@RequestMapping("/")
public String index() { // <7>
public String index() { // <6>
return INDEX_TEMPLATE_VIEW_NAME;
}
@RequestMapping(method = RequestMethod.GET, path = "/ping")
@ResponseBody
public String ping() { // <8>
public String ping() { // <7>
return PING_RESPONSE;
}
@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) { // <9>
@RequestParam(name = "attributeValue", required = false) String value) { // <8>
modelMap.addAttribute("sessionAttributes",
attributes(setAttribute(updateRequestCount(session), name, value)));
attributes(setAttribute(updateRequestCount(session), name, value)));
return INDEX_TEMPLATE_VIEW_NAME;
}
@@ -230,27 +209,24 @@ public class Application {
@SuppressWarnings("all")
HttpSession updateRequestCount(HttpSession session) {
synchronized (session) {
Integer currentRequestCount = (Integer) session
.getAttribute(REQUEST_COUNT_ATTRIBUTE_NAME);
session.setAttribute(REQUEST_COUNT_ATTRIBUTE_NAME,
nullSafeIncrement(currentRequestCount));
Integer currentRequestCount = (Integer) session.getAttribute(REQUEST_COUNT_ATTRIBUTE_NAME);
session.setAttribute(REQUEST_COUNT_ATTRIBUTE_NAME, nullSafeIncrement(currentRequestCount));
return session;
}
}
/* (non-Javadoc) */
Integer nullSafeIncrement(Integer value) {
return (nullSafeInt(value) + 1);
return (nullSafeIntValue(value) + 1);
}
/* (non-Javadoc) */
int nullSafeInt(Number value) {
int nullSafeIntValue(Number value) {
return (value != null ? value.intValue() : 0);
}
/* (non-Javadoc) */
HttpSession setAttribute(HttpSession session, String attributeName,
String attributeValue) {
HttpSession setAttribute(HttpSession session, String attributeName, String attributeValue) {
if (isSet(attributeName, attributeValue)) {
session.setAttribute(attributeName, attributeValue);
}
@@ -269,97 +245,25 @@ public class Application {
return set;
}
/* (non-Javadoc) */
Map<String, String> attributes(HttpSession session) {
Map<String, String> sessionAttributes = new HashMap<String, String>();
for (String attributeName : toIterable(session.getAttributeNames())) {
sessionAttributes.put(attributeName,
String.valueOf(session.getAttribute(attributeName)));
String.valueOf(session.getAttribute(attributeName)));
}
return sessionAttributes;
}
/* (non-Javadoc) */
<T> Iterable<T> toIterable(final Enumeration<T> enumeration) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return (enumeration == null ? Collections.<T>emptyIterator()
: new Iterator<T>() {
public boolean hasNext() {
return enumeration.hasMoreElements();
}
public T next() {
return enumeration.nextElement();
}
public void remove() {
throw new UnsupportedOperationException(
"Auto-generated method stub");
}
});
: CollectionUtils.toIterator(enumeration));
}
};
}
/* (non-Javadoc) */
boolean waitForCacheServerToStart(String host, int port) {
return waitForCacheServerToStart(host, port, DEFAULT_WAIT_DURATION);
}
/* (non-Javadoc) */
boolean waitForCacheServerToStart(final String host, final int port, long duration) {
return waitOnCondition(new Condition() {
AtomicBoolean connected = new AtomicBoolean(false);
public boolean evaluate() {
Socket socket = null;
try {
// NOTE: this code is not intended to be an atomic, compound action (a
// possible race condition);
// opening another connection (at the expense of using system
// resources) after connectivity
// has already been established is not detrimental in this use case
if (!this.connected.get()) {
socket = new Socket(host, port);
this.connected.set(true);
}
}
catch (IOException ignore) {
}
finally {
GemFireUtils.close(socket);
}
return this.connected.get();
}
}, duration);
}
boolean waitOnCondition(Condition condition) {
return waitOnCondition(condition, DEFAULT_WAIT_DURATION);
}
@SuppressWarnings("all")
boolean waitOnCondition(Condition condition, long duration) {
final long timeout = (System.currentTimeMillis() + duration);
try {
while (!condition.evaluate() && System.currentTimeMillis() < timeout) {
synchronized (condition) {
TimeUnit.MILLISECONDS.timedWait(condition, DEFAULT_WAIT_INTERVAL);
}
}
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return condition.evaluate();
}
interface Condition {
boolean evaluate();
}
}