diff --git a/samples/boot/build.gradle b/samples/boot/build.gradle index ef3c77d0..0f97a380 100644 --- a/samples/boot/build.gradle +++ b/samples/boot/build.gradle @@ -17,10 +17,10 @@ group = 'samples' dependencies { compile project(':spring-session'), + project(':samples:spring-embedded-redis'), "org.springframework.boot:spring-boot-starter-redis", "org.springframework.boot:spring-boot-starter-web", "org.springframework.boot:spring-boot-starter-thymeleaf", - "redis.embedded:embedded-redis:$embeddedRedisVersion", "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect", "org.springframework.security:spring-security-web:$springSecurityVersion", "org.springframework.security:spring-security-config:$springSecurityVersion" diff --git a/samples/boot/src/main/java/sample/config/EmbeddedRedisConfiguration.java b/samples/boot/src/main/java/sample/config/EmbeddedRedisConfiguration.java deleted file mode 100644 index b380d397..00000000 --- a/samples/boot/src/main/java/sample/config/EmbeddedRedisConfiguration.java +++ /dev/null @@ -1,68 +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; - -/** - * 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 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/samples/boot/src/main/java/sample/config/HttpSessionConfig.java b/samples/boot/src/main/java/sample/config/HttpSessionConfig.java index 5bb05052..04c9b652 100644 --- a/samples/boot/src/main/java/sample/config/HttpSessionConfig.java +++ b/samples/boot/src/main/java/sample/config/HttpSessionConfig.java @@ -17,6 +17,9 @@ package sample.config; import org.springframework.session.data.redis.config.annotation.web.http.*; +import sample.EnableEmbeddedRedis; + +@EnableEmbeddedRedis // tag::class[] @EnableRedisHttpSession // <1> public class HttpSessionConfig { } diff --git a/samples/httpsession-xml/build.gradle b/samples/httpsession-xml/build.gradle index 03d98aa0..96ec9209 100644 --- a/samples/httpsession-xml/build.gradle +++ b/samples/httpsession-xml/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/httpsession-xml/src/main/java/sample/RedisServerBean.java b/samples/httpsession-xml/src/main/java/sample/RedisServerBean.java deleted file mode 100644 index 1d0f9a13..00000000 --- a/samples/httpsession-xml/src/main/java/sample/RedisServerBean.java +++ /dev/null @@ -1,53 +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 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 - */ -public 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/samples/httpsession-xml/src/main/webapp/WEB-INF/spring/session.xml b/samples/httpsession-xml/src/main/webapp/WEB-INF/spring/session.xml index 4856ecd4..250c72bc 100644 --- a/samples/httpsession-xml/src/main/webapp/WEB-INF/spring/session.xml +++ b/samples/httpsession-xml/src/main/webapp/WEB-INF/spring/session.xml @@ -2,15 +2,17 @@ + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - + - + \ No newline at end of file diff --git a/samples/httpsession/build.gradle b/samples/httpsession/build.gradle index 758d7276..f8215de3 100644 --- a/samples/httpsession/build.gradle +++ b/samples/httpsession/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/httpsession/src/main/java/sample/Config.java b/samples/httpsession/src/main/java/sample/Config.java index 7db58d9d..2c05f8d9 100644 --- a/samples/httpsession/src/main/java/sample/Config.java +++ b/samples/httpsession/src/main/java/sample/Config.java @@ -16,18 +16,19 @@ package sample; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.data.redis.connection.jedis.*; -import org.springframework.session.data.redis.config.annotation.web.http.*; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; // tag::class[] -@Import(EmbeddedRedisConfiguration.class) // <1> +@EnableEmbeddedRedis // <1> @EnableRedisHttpSession // <2> public class Config { @Bean - public JedisConnectionFactory connectionFactory() { - return new JedisConnectionFactory(); // <3> + public JedisConnectionFactory connectionFactory(@RedisServerPort int port) { + JedisConnectionFactory connection = new JedisConnectionFactory(); // <3> + connection.setPort(port); + return connection; } } // end::class[] \ No newline at end of file diff --git a/samples/httpsession/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/httpsession/src/main/java/sample/EmbeddedRedisConfiguration.java deleted file mode 100644 index c50d54c1..00000000 --- a/samples/httpsession/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 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/samples/rest/build.gradle b/samples/rest/build.gradle index 7d13c86d..66f8ab18 100644 --- a/samples/rest/build.gradle +++ b/samples/rest/build.gradle @@ -8,8 +8,8 @@ sonarRunner { dependencies { compile project(':spring-session-data-redis'), + project(':samples:spring-embedded-redis'), "org.springframework:spring-webmvc:$springVersion", - "redis.embedded:embedded-redis:$embeddedRedisVersion", "org.springframework.security:spring-security-config:$springSecurityVersion", "org.springframework.security:spring-security-web:$springSecurityVersion", "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion", diff --git a/samples/rest/src/main/java/sample/HttpSessionConfig.java b/samples/rest/src/main/java/sample/HttpSessionConfig.java index 4bda2b52..aa52fa30 100644 --- a/samples/rest/src/main/java/sample/HttpSessionConfig.java +++ b/samples/rest/src/main/java/sample/HttpSessionConfig.java @@ -15,10 +15,8 @@ */ package sample; -import org.springframework.beans.factory.annotation.Value; 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; import org.springframework.session.web.http.HeaderHttpSessionStrategy; @@ -26,12 +24,12 @@ import org.springframework.session.web.http.HttpSessionStrategy; // tag::class[] @Configuration -@Import(EmbeddedRedisConfiguration.class) // <1> +@EnableEmbeddedRedis // <1> @EnableRedisHttpSession // <2> public class HttpSessionConfig { @Bean - public JedisConnectionFactory connectionFactory(@Value("${redis.server.port}") int port) { + public JedisConnectionFactory connectionFactory(@RedisServerPort int port) { JedisConnectionFactory factory = new JedisConnectionFactory(); // <3> factory.setPort(port); return factory; diff --git a/samples/rest/src/test/resources/application.properties b/samples/rest/src/test/resources/application.properties deleted file mode 100644 index bd3846d5..00000000 --- a/samples/rest/src/test/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -redis.server.port=12345 \ No newline at end of file diff --git a/samples/security/build.gradle b/samples/security/build.gradle index 5ded8deb..61e77fe7 100644 --- a/samples/security/build.gradle +++ b/samples/security/build.gradle @@ -8,6 +8,7 @@ sonarRunner { dependencies { compile project(':spring-session-data-redis'), + project(':samples:spring-embedded-redis'), "org.springframework:spring-web:$springVersion", "redis.embedded:embedded-redis:$embeddedRedisVersion", "org.springframework.security:spring-security-config:$springSecurityVersion", diff --git a/samples/security/src/main/java/sample/Config.java b/samples/security/src/main/java/sample/Config.java index 3b749f11..6be1a4ae 100644 --- a/samples/security/src/main/java/sample/Config.java +++ b/samples/security/src/main/java/sample/Config.java @@ -17,19 +17,20 @@ 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; // tag::class[] @Configuration -@Import(EmbeddedRedisConfiguration.class) // <1> +@EnableEmbeddedRedis // <1> @EnableRedisHttpSession // <2> public class Config { @Bean - public JedisConnectionFactory connectionFactory() { - return new JedisConnectionFactory(); // <3> + public JedisConnectionFactory connectionFactory(@RedisServerPort int port) { + JedisConnectionFactory connection = new JedisConnectionFactory(); // <3> + connection.setPort(port); + return connection; } } // end::class[] \ No newline at end of file diff --git a/samples/security/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/security/src/main/java/sample/EmbeddedRedisConfiguration.java deleted file mode 100644 index a8083ea3..00000000 --- a/samples/security/src/main/java/sample/EmbeddedRedisConfiguration.java +++ /dev/null @@ -1,69 +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 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/samples/spring-embedded-redis/build.gradle b/samples/spring-embedded-redis/build.gradle new file mode 100644 index 00000000..f9a93c88 --- /dev/null +++ b/samples/spring-embedded-redis/build.gradle @@ -0,0 +1,14 @@ +apply from: JAVA_GRADLE + +tasks.findByPath("artifactoryPublish")?.enabled = false +sonarRunner { + skipProject = true +} + +dependencies { + compile "redis.embedded:embedded-redis:$embeddedRedisVersion", + "org.springframework:spring-context:$springVersion" + + testCompile "junit:junit:$junitVersion", + "org.springframework.security:spring-security-test:$springSecurityVersion" +} \ No newline at end of file diff --git a/samples/rest/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/spring-embedded-redis/src/main/java/sample/EmbeddedRedisConfiguration.java similarity index 87% rename from samples/rest/src/main/java/sample/EmbeddedRedisConfiguration.java rename to samples/spring-embedded-redis/src/main/java/sample/EmbeddedRedisConfiguration.java index e543d4c6..29594a18 100644 --- a/samples/rest/src/main/java/sample/EmbeddedRedisConfiguration.java +++ b/samples/spring-embedded-redis/src/main/java/sample/EmbeddedRedisConfiguration.java @@ -14,6 +14,7 @@ * limitations under the License. */ package sample; + import java.io.IOException; import java.net.ServerSocket; @@ -39,8 +40,8 @@ import redis.embedded.RedisServer; * @author Rob Winch */ @Configuration -//@org.springframework.context.annotation.PropertySource("classpath:application.properties") -public class EmbeddedRedisConfiguration { +class EmbeddedRedisConfiguration { + public static final String SERVER_PORT_PROP_NAME = "spring.redis.port"; @Bean public static RedisServerBean redisServer(ConfigurableEnvironment env) { @@ -55,13 +56,13 @@ public class EmbeddedRedisConfiguration { } /** - * 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. + * 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. We also want to ensure that we are able to register the + * {@link PropertySource} before any beans are initialized. */ static class RedisServerBean extends PropertySource implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - public static final String SERVER_PORT_PROP_NAME = "redis.server.port"; private final int port = getAvailablePort(); private RedisServer redisServer; @@ -102,7 +103,9 @@ public class EmbeddedRedisConfiguration { throw new RuntimeException(e); } finally { try { - socket.close(); + if(socket != null) { + socket.close(); + } }catch(IOException e) {} } } diff --git a/samples/spring-embedded-redis/src/main/java/sample/EnableEmbeddedRedis.java b/samples/spring-embedded-redis/src/main/java/sample/EnableEmbeddedRedis.java new file mode 100644 index 00000000..03c85662 --- /dev/null +++ b/samples/spring-embedded-redis/src/main/java/sample/EnableEmbeddedRedis.java @@ -0,0 +1,64 @@ +/* + * 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.Retention; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + *

+ * 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 { @Configuration @EnableRedisHttpSession + @EnableEmbeddedRedis static class Config { @Bean - public JedisConnectionFactory connectionFactory() throws Exception { + public JedisConnectionFactory connectionFactory(@RedisServerPort int port) throws Exception { JedisConnectionFactory factory = new JedisConnectionFactory(); - factory.setPort(getPort()); + factory.setPort(port); factory.setUsePool(false); return factory; } - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } - @Bean public SessionDestroyedEventRegistry sessionDestroyedEventRegistry() { return new SessionDestroyedEventRegistry(); } - - /** - * 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(getPort()); - 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 {} - } - } - - private static Integer availablePort; - - private static int getPort() throws IOException { - if(availablePort == null) { - ServerSocket socket = new ServerSocket(0); - availablePort = socket.getLocalPort(); - socket.close(); - } - return availablePort; } } \ No newline at end of file diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java index a6b568bd..3e51912a 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java @@ -18,22 +18,14 @@ package org.springframework.session.data.redis.config.annotation.web.http; 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 @@ -116,60 +110,19 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests + *
  * {@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. *