+ * Runs an embedded Redis instance on a random available port.This is only necessary + * sincewe do not want users to have to setup a Redis instance. In a production + * environment, this would not be used since a Redis Server would be setup. + *
+ *+ * The port being used can be identified by using {@literal @RedisServerPort} on a Spring + * Bean. For example: + *
+ * + *
+ * {@literal @Configuration}
+ * {@literal @EnableEmbeddedRedis}
+ * public class RedisHttpSessionConfig {
+ *
+ * {@literal @Bean}
+ * public JedisConnectionFactory connectionFactory({@literal @RedisServerPort} int port) throws Exception {
+ * JedisConnectionFactory connection = new JedisConnectionFactory();
+ * connection.setPort(port);
+ * return connection;
+ * }
+ *
+ * }
+ *
+ *
+ * See spring-projects/spring-session/issues/121 for details on exposing embedded Redis
+ * support.
+ *
+ * @author Rob Winch
+ * @see RedisServerPort
+ *
+ */
+@Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)
+@Target(value={java.lang.annotation.ElementType.TYPE})
+@Documented
+@Import(EmbeddedRedisConfiguration.class)
+@Configuration
+public @interface EnableEmbeddedRedis {}
diff --git a/samples/spring-embedded-redis/src/main/java/sample/RedisServerPort.java b/samples/spring-embedded-redis/src/main/java/sample/RedisServerPort.java
new file mode 100644
index 00000000..d6d73283
--- /dev/null
+++ b/samples/spring-embedded-redis/src/main/java/sample/RedisServerPort.java
@@ -0,0 +1,50 @@
+/*
+ * 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.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.beans.factory.annotation.Value;
+
+/**
+ * A convenience for finding the Redis Server port when using {@link EnableEmbeddedRedis}. For example:
+ *
+ *
+ * {@literal @Configuration}
+ * {@literal @EnableEmbeddedRedis}
+ * public class RedisHttpSessionConfig {
+ *
+ * {@literal @Bean}
+ * public JedisConnectionFactory connectionFactory({@literal @RedisServerPort} int port) throws Exception {
+ * JedisConnectionFactory connection = new JedisConnectionFactory();
+ * connection.setPort(port);
+ * return connection;
+ * }
+ *
+ * }
+ *
+ *
+ * @author Rob Winch
+ */
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Value("${"+EmbeddedRedisConfiguration.SERVER_PORT_PROP_NAME+"}")
+public @interface RedisServerPort { }
diff --git a/samples/users/build.gradle b/samples/users/build.gradle
index 758d7276..f8215de3 100644
--- a/samples/users/build.gradle
+++ b/samples/users/build.gradle
@@ -8,8 +8,8 @@ sonarRunner {
dependencies {
compile project(':spring-session-data-redis'),
+ project(':samples:spring-embedded-redis'),
"org.springframework:spring-web:$springVersion",
- "redis.embedded:embedded-redis:$embeddedRedisVersion",
jstlDependencies
providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion"
diff --git a/samples/users/src/main/java/sample/Config.java b/samples/users/src/main/java/sample/Config.java
index 8a0a95ef..05a7386d 100644
--- a/samples/users/src/main/java/sample/Config.java
+++ b/samples/users/src/main/java/sample/Config.java
@@ -17,22 +17,24 @@ package sample;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
* @author Rob Winch
*/
+
+@EnableEmbeddedRedis
// tag::class[]
-@Import(EmbeddedRedisConfiguration.class)
@Configuration
@EnableRedisHttpSession
public class Config {
@Bean
- public JedisConnectionFactory connectionFactory() {
- return new JedisConnectionFactory();
+ public JedisConnectionFactory connectionFactory(@RedisServerPort int port) {
+ JedisConnectionFactory connection = new JedisConnectionFactory();
+ connection.setPort(port);
+ return connection;
}
}
// end::class[]
\ No newline at end of file
diff --git a/samples/users/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/users/src/main/java/sample/EmbeddedRedisConfiguration.java
deleted file mode 100644
index b0a344f8..00000000
--- a/samples/users/src/main/java/sample/EmbeddedRedisConfiguration.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.beans.BeansException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import redis.clients.jedis.Protocol;
-import redis.embedded.RedisServer;
-
-/**
- * Runs an embedded Redis instance. This is only necessary since we do not want
- * users to have to setup a Redis instance. In a production environment, this
- * would not be used since a Redis Server would be setup.
- *
- * @author Rob Winch
- */
-@Configuration
-public class EmbeddedRedisConfiguration {
-
- @Bean
- public RedisServerBean redisServer() {
- return new RedisServerBean();
- }
-
- /**
- * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean
- * is initialized before any other Beans. Specifically, we want to ensure
- * that the Redis Server is started before RedisHttpSessionConfiguration
- * attempts to enable Keyspace notifications.
- */
- class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor {
- private RedisServer redisServer;
-
-
- public void afterPropertiesSet() throws Exception {
- redisServer = new RedisServer(Protocol.DEFAULT_PORT);
- redisServer.start();
- }
-
- public void destroy() throws Exception {
- if(redisServer != null) {
- redisServer.stop();
- }
- }
-
- public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {}
-
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
- }
-}
diff --git a/samples/websocket/build.gradle b/samples/websocket/build.gradle
index 39fab1dd..292eccc2 100644
--- a/samples/websocket/build.gradle
+++ b/samples/websocket/build.gradle
@@ -18,13 +18,13 @@ group = 'samples'
dependencies {
compile project(':spring-session-data-redis'),
+ project(':samples:spring-embedded-redis'),
"org.springframework.boot:spring-boot-starter-web",
"org.springframework.boot:spring-boot-starter-data-jpa",
"org.springframework.boot:spring-boot-starter-thymeleaf",
"org.springframework.boot:spring-boot-starter-websocket",
"org.springframework:spring-websocket:${springVersion}",
"org.springframework.data:spring-data-jpa:1.7.0.RELEASE",
- "redis.embedded:embedded-redis:$embeddedRedisVersion",
"nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect",
"com.h2database:h2",
"org.springframework.security:spring-security-web:$springSecurityVersion",
diff --git a/samples/websocket/src/main/java/sample/config/DataSourceConfig.java b/samples/websocket/src/main/java/sample/config/DataSourceConfig.java
index dc09be9d..f2804f52 100644
--- a/samples/websocket/src/main/java/sample/config/DataSourceConfig.java
+++ b/samples/websocket/src/main/java/sample/config/DataSourceConfig.java
@@ -23,6 +23,8 @@ import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import sample.RedisServerPort;
+
@Configuration
public class DataSourceConfig {
@@ -33,7 +35,9 @@ public class DataSourceConfig {
}
@Bean
- public JedisConnectionFactory connectionFactory() throws Exception {
- return new JedisConnectionFactory();
+ public JedisConnectionFactory connectionFactory(@RedisServerPort int port) {
+ JedisConnectionFactory connection = new JedisConnectionFactory(); // <3>
+ connection.setPort(port);
+ return connection;
}
}
diff --git a/samples/websocket/src/main/java/sample/config/EmbeddedRedisConfig.java b/samples/websocket/src/main/java/sample/config/EmbeddedRedisConfig.java
deleted file mode 100644
index 1b32587e..00000000
--- a/samples/websocket/src/main/java/sample/config/EmbeddedRedisConfig.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.config;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import redis.clients.jedis.Protocol;
-import redis.embedded.RedisServer;
-
-/**
- * @author Rob Winch
- */
-@Configuration
-public class EmbeddedRedisConfig {
-
- @Bean
- public static RedisServerBean redisServer() {
- return new RedisServerBean();
- }
-
- /**
- * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean
- * is initialized before any other Beans. Specifically, we want to ensure
- * that the Redis Server is started before RedisHttpSessionConfiguration
- * attempts to enable Keyspace notifications.
- */
- static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor {
- private RedisServer redisServer;
-
-
- public void afterPropertiesSet() throws Exception {
- redisServer = new RedisServer(Protocol.DEFAULT_PORT);
- redisServer.start();
- }
-
- public void destroy() throws Exception {
- if(redisServer != null) {
- redisServer.stop();
- }
- }
-
- public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {}
-
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
- }
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 60f0c6e5..5ef8d7a0 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -3,6 +3,7 @@ rootProject.name = 'spring-session-build'
include 'docs'
include 'samples:boot'
+include 'samples:spring-embedded-redis'
include 'samples:hazelcast'
include 'samples:httpsession'
include 'samples:httpsession-xml'
diff --git a/spring-session/build.gradle b/spring-session/build.gradle
index 16d853e8..62c538b3 100644
--- a/spring-session/build.gradle
+++ b/spring-session/build.gradle
@@ -20,9 +20,10 @@ dependencies {
"org.springframework:spring-messaging:$springVersion",
"org.springframework:spring-websocket:$springVersion"
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
- integrationTestCompile "redis.clients:jedis:2.4.1",
- "org.apache.commons:commons-pool2:2.2",
- "redis.embedded:embedded-redis:$embeddedRedisVersion"
+ integrationTestCompile project(':samples:spring-embedded-redis'),
+ "redis.clients:jedis:2.4.1",
+ "org.apache.commons:commons-pool2:2.2"
+
testCompile "junit:junit:$junitVersion",
'org.mockito:mockito-core:1.9.5',
"org.springframework:spring-test:$springVersion",
diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java b/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java
index b824a018..2df2e128 100644
--- a/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java
+++ b/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java
@@ -17,22 +17,14 @@ package org.springframework.session.data.redis;
import static org.fest.assertions.Assertions.assertThat;
-import java.io.IOException;
-import java.net.ServerSocket;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -47,7 +39,9 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
-import redis.embedded.RedisServer;
+import sample.EmbeddedRedisConfiguration;
+import sample.EnableEmbeddedRedis;
+import sample.RedisServerPort;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@@ -133,60 +127,19 @@ public class RedisOperationsSessionRepositoryITests
* {@literal @Configuration}
* {@literal @EnableRedisHttpSession}
* public class RedisHttpSessionConfig {
@@ -40,7 +40,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
* }
*
* }
- *
+ *
*
* More advanced configurations can extend {@link RedisHttpSessionConfiguration} instead.
*