From 17aa3eed03a1edc3aa1e0012c8a26b462c476374 Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Wed, 7 Jun 2017 22:38:35 +0200 Subject: [PATCH 1/3] Use TestContainers for integration tests --- .travis.yml | 12 +-- gradle/dependency-management.gradle | 10 +++ ...-session-sample-boot-findbyusername.gradle | 1 + .../java/sample/FindByUsernameTests.java | 30 ++++++- ...ring-session-sample-boot-redis-json.gradle | 1 + .../java/sample/HttpRedisJsonTest.java | 30 ++++++- .../java/sample/RedisSerializerTest.java | 38 ++++++++- .../spring-session-sample-boot-redis.gradle | 1 + .../java/sample/BootTests.java | 30 ++++++- ...pring-session-sample-boot-websocket.gradle | 1 + .../test/java/sample/ApplicationTests.java | 37 ++++++++- ...ring-session-sample-javaconfig-rest.gradle | 2 + .../java/rest/RestMockMvcTests.java | 41 ++++++++-- .../spring-session-data-redis.gradle | 1 + .../session/data/AbstractITests.java | 63 --------------- .../data/redis/AbstractRedisITests.java | 51 ++++++++++++ ...edisOperationsSessionRepositoryITests.java | 45 ++++++++--- ...ttpSessionExpireSessionDestroyedTests.java | 14 ++-- .../RedisHttpSessionConfig.java | 36 --------- ...ssionRepositoryFlushImmediatelyITests.java | 16 +++- ...isListenerContainerTaskExecutorITests.java | 23 +++--- .../spring-session-jdbc.gradle | 8 +- ...JdbcOperationsSessionRepositoryITests.java | 7 -- ...JdbcOperationsSessionRepositoryITests.java | 79 +++++++++++++++++++ ...JdbcOperationsSessionRepositoryITests.java | 79 +++++++++++++++++++ ...JdbcOperationsSessionRepositoryITests.java | 76 ++++++++++++++++++ ...JdbcOperationsSessionRepositoryITests.java | 78 ++++++++++++++++++ 27 files changed, 650 insertions(+), 160 deletions(-) delete mode 100644 spring-session-data-redis/src/integration-test/java/org/springframework/session/data/AbstractITests.java create mode 100644 spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/AbstractRedisITests.java delete mode 100644 spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisHttpSessionConfig.java create mode 100644 spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB10JdbcOperationsSessionRepositoryITests.java create mode 100644 spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB5JdbcOperationsSessionRepositoryITests.java create mode 100644 spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MySQL5JdbcOperationsSessionRepositoryITests.java create mode 100644 spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/PostgreSQL9JdbcOperationsSessionRepositoryITests.java diff --git a/.travis.yml b/.travis.yml index 424d891c7..e2b771eed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,20 @@ language: java -services: - - redis-server +sudo: required -jdk: - - oraclejdk8 +services: docker -os: - - linux +jdk: oraclejdk8 before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + cache: directories: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ install: true + script: ./gradlew clean build --refresh-dependencies --no-daemon diff --git a/gradle/dependency-management.gradle b/gradle/dependency-management.gradle index 0e442d3db..a6fbfd60c 100644 --- a/gradle/dependency-management.gradle +++ b/gradle/dependency-management.gradle @@ -12,6 +12,12 @@ dependencyManagement { entry 'hazelcast-client' } + dependencySet(group: 'org.testcontainers', version: '1.4.2') { + entry 'mysql' + entry 'postgresql' + entry 'testcontainers' + } + dependency 'com.fasterxml.jackson.core:jackson-databind:2.9.0.pr4' dependency 'com.h2database:h2:1.4.196' dependency 'com.maxmind.geoip2:geoip2:2.3.1' @@ -22,13 +28,17 @@ dependencyManagement { dependency 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b02' dependency 'javax.servlet:javax.servlet-api:3.1.0' dependency 'junit:junit:4.12' + dependency 'mysql:mysql-connector-java:5.1.43' dependency 'org.apache.derby:derby:10.13.1.1' dependency 'org.apache.httpcomponents:httpclient:4.5.3' dependency 'org.apache.taglibs:taglibs-standard-jstlel:1.2.5' dependency 'org.assertj:assertj-core:3.8.0' dependency 'org.hsqldb:hsqldb:2.4.0' + dependency 'org.mariadb.jdbc:mariadb-java-client:2.0.3' dependency 'org.mockito:mockito-core:2.8.47' + dependency 'org.postgresql:postgresql:42.1.3' dependency 'org.seleniumhq.selenium:htmlunit-driver:2.27' + dependency 'org.testcontainers:mariadb:1.3.0' dependency 'org.webjars:bootstrap:2.3.2' dependency 'org.webjars:html5shiv:3.7.3' dependency 'org.webjars:jquery:1.9.0' diff --git a/samples/boot/findbyusername/spring-session-sample-boot-findbyusername.gradle b/samples/boot/findbyusername/spring-session-sample-boot-findbyusername.gradle index bb1f2a9d9..d994f177e 100644 --- a/samples/boot/findbyusername/spring-session-sample-boot-findbyusername.gradle +++ b/samples/boot/findbyusername/spring-session-sample-boot-findbyusername.gradle @@ -18,6 +18,7 @@ dependencies { testCompile "org.assertj:assertj-core" integrationTestCompile seleniumDependencies + integrationTestCompile "org.testcontainers:testcontainers" } integrationTest { diff --git a/samples/boot/findbyusername/src/integration-test/java/sample/FindByUsernameTests.java b/samples/boot/findbyusername/src/integration-test/java/sample/FindByUsernameTests.java index 12ed00bc1..32ad62d9b 100644 --- a/samples/boot/findbyusername/src/integration-test/java/sample/FindByUsernameTests.java +++ b/samples/boot/findbyusername/src/integration-test/java/sample/FindByUsernameTests.java @@ -18,9 +18,11 @@ import org.junit.After; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.WebDriver; +import org.testcontainers.containers.GenericContainer; import sample.pages.HomePage; import sample.pages.LoginPage; @@ -28,6 +30,10 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder; @@ -35,12 +41,20 @@ /** * @author Eddú Meléndez * @author Rob Winch + * @author Vedran Pavic */ @RunWith(SpringRunner.class) @AutoConfigureMockMvc -@SpringBootTest(webEnvironment = WebEnvironment.MOCK) +@SpringBootTest(classes = FindByUsernameApplication.class, webEnvironment = WebEnvironment.MOCK) +@ContextConfiguration(initializers = FindByUsernameTests.Initializer.class) public class FindByUsernameTests { + private static final String DOCKER_IMAGE = "redis:3.2.9"; + + @ClassRule + public static GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE) + .withExposedPorts(6379); + @Autowired private MockMvc mockMvc; @@ -72,4 +86,18 @@ public void login() { home.terminateButtonDisabled(); } + static class Initializer + implements ApplicationContextInitializer { + + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + TestPropertyValues + .of("spring.redis.host=" + redisContainer.getContainerIpAddress(), + "spring.redis.port=" + redisContainer.getFirstMappedPort()) + .applyTo(configurableApplicationContext.getEnvironment()); + } + + } + } diff --git a/samples/boot/redis-json/spring-session-sample-boot-redis-json.gradle b/samples/boot/redis-json/spring-session-sample-boot-redis-json.gradle index fec2cba1c..66e326119 100644 --- a/samples/boot/redis-json/spring-session-sample-boot-redis-json.gradle +++ b/samples/boot/redis-json/spring-session-sample-boot-redis-json.gradle @@ -18,4 +18,5 @@ dependencies { testCompile "org.skyscreamer:jsonassert" integrationTestCompile seleniumDependencies + integrationTestCompile "org.testcontainers:testcontainers" } diff --git a/samples/boot/redis-json/src/integration-test/java/sample/HttpRedisJsonTest.java b/samples/boot/redis-json/src/integration-test/java/sample/HttpRedisJsonTest.java index d777fc34a..21de665b9 100644 --- a/samples/boot/redis-json/src/integration-test/java/sample/HttpRedisJsonTest.java +++ b/samples/boot/redis-json/src/integration-test/java/sample/HttpRedisJsonTest.java @@ -20,9 +20,11 @@ import org.junit.After; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.WebDriver; +import org.testcontainers.containers.GenericContainer; import sample.pages.HomePage; import sample.pages.HomePage.Attribute; import sample.pages.LoginPage; @@ -31,6 +33,10 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder; @@ -39,12 +45,20 @@ /** * @author Eddú Meléndez + * @author Vedran Pavic */ @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = WebEnvironment.MOCK) +@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.MOCK) @AutoConfigureMockMvc +@ContextConfiguration(initializers = HttpRedisJsonTest.Initializer.class) public class HttpRedisJsonTest { + private static final String DOCKER_IMAGE = "redis:3.2.9"; + + @ClassRule + public static GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE) + .withExposedPorts(6379); + @Autowired private MockMvc mockMvc; @@ -96,4 +110,18 @@ public void createAttribute() { assertThat(attributes).extracting("attributeValue").contains("Demo Value"); } + static class Initializer + implements ApplicationContextInitializer { + + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + TestPropertyValues + .of("spring.redis.host=" + redisContainer.getContainerIpAddress(), + "spring.redis.port=" + redisContainer.getFirstMappedPort()) + .applyTo(configurableApplicationContext.getEnvironment()); + } + + } + } diff --git a/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java b/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java index e44c47276..c3aa04f10 100644 --- a/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java +++ b/samples/boot/redis-json/src/integration-test/java/sample/RedisSerializerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -13,28 +13,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package sample; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; +import org.testcontainers.containers.GenericContainer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; /** - * @author jitendra on 8/3/16. + * @author jitendra + * @author Vedran Pavic */ @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(classes = Application.class) +@ContextConfiguration(initializers = RedisSerializerTest.Initializer.class) public class RedisSerializerTest { + private static final String DOCKER_IMAGE = "redis:3.2.9"; + + @ClassRule + public static GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE) + .withExposedPorts(6379); + @Autowired - RedisTemplate sessionRedisTemplate; + private RedisTemplate sessionRedisTemplate; @Test public void testRedisTemplate() { @@ -43,4 +58,19 @@ public void testRedisTemplate() { assertThat(this.sessionRedisTemplate.getDefaultSerializer()) .isInstanceOf(GenericJackson2JsonRedisSerializer.class); } + + static class Initializer + implements ApplicationContextInitializer { + + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + TestPropertyValues + .of("spring.redis.host=" + redisContainer.getContainerIpAddress(), + "spring.redis.port=" + redisContainer.getFirstMappedPort()) + .applyTo(configurableApplicationContext.getEnvironment()); + } + + } + } diff --git a/samples/boot/redis/spring-session-sample-boot-redis.gradle b/samples/boot/redis/spring-session-sample-boot-redis.gradle index 9dc3cc81d..d5845dcfb 100644 --- a/samples/boot/redis/spring-session-sample-boot-redis.gradle +++ b/samples/boot/redis/spring-session-sample-boot-redis.gradle @@ -15,4 +15,5 @@ dependencies { testCompile "org.springframework.boot:spring-boot-starter-test" integrationTestCompile seleniumDependencies + integrationTestCompile "org.testcontainers:testcontainers" } diff --git a/samples/boot/redis/src/integration-test/java/sample/BootTests.java b/samples/boot/redis/src/integration-test/java/sample/BootTests.java index 0caa91250..11f2bd171 100644 --- a/samples/boot/redis/src/integration-test/java/sample/BootTests.java +++ b/samples/boot/redis/src/integration-test/java/sample/BootTests.java @@ -18,9 +18,11 @@ import org.junit.After; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.WebDriver; +import org.testcontainers.containers.GenericContainer; import sample.pages.HomePage; import sample.pages.LoginPage; @@ -28,18 +30,30 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder; /** * @author Eddú Meléndez + * @author Vedran Pavic */ @RunWith(SpringRunner.class) @AutoConfigureMockMvc -@SpringBootTest(webEnvironment = WebEnvironment.MOCK) +@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.MOCK) +@ContextConfiguration(initializers = BootTests.Initializer.class) public class BootTests { + private static final String DOCKER_IMAGE = "redis:3.2.9"; + + @ClassRule + public static GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE) + .withExposedPorts(6379); + @Autowired private MockMvc mockMvc; @@ -78,4 +92,18 @@ public void logout() { login.assertAt(); } + static class Initializer + implements ApplicationContextInitializer { + + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + TestPropertyValues + .of("spring.redis.host=" + redisContainer.getContainerIpAddress(), + "spring.redis.port=" + redisContainer.getFirstMappedPort()) + .applyTo(configurableApplicationContext.getEnvironment()); + } + + } + } diff --git a/samples/boot/websocket/spring-session-sample-boot-websocket.gradle b/samples/boot/websocket/spring-session-sample-boot-websocket.gradle index f73e634b4..6d5906859 100644 --- a/samples/boot/websocket/spring-session-sample-boot-websocket.gradle +++ b/samples/boot/websocket/spring-session-sample-boot-websocket.gradle @@ -23,4 +23,5 @@ dependencies { testCompile "org.springframework.boot:spring-boot-starter-test" testCompile "org.springframework.security:spring-security-test" + testCompile "org.testcontainers:testcontainers" } diff --git a/samples/boot/websocket/src/test/java/sample/ApplicationTests.java b/samples/boot/websocket/src/test/java/sample/ApplicationTests.java index a5b9d5b56..4142fa8b9 100644 --- a/samples/boot/websocket/src/test/java/sample/ApplicationTests.java +++ b/samples/boot/websocket/src/test/java/sample/ApplicationTests.java @@ -20,14 +20,21 @@ import java.util.List; import java.util.concurrent.ExecutionException; +import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; +import org.testcontainers.containers.GenericContainer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.web.socket.TextMessage; @@ -41,18 +48,27 @@ /** * @author Rob Winch + * @author Vedran Pavic */ @RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@ContextConfiguration(initializers = ApplicationTests.Initializer.class) public class ApplicationTests { + + private static final String DOCKER_IMAGE = "redis:3.2.9"; + + @ClassRule + public static GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE) + .withExposedPorts(6379); + @Rule public final ExpectedException thrown = ExpectedException.none(); @Value("${local.server.port}") - String port; + private String port; @Autowired - WebSocketHandler webSocketHandler; + private WebSocketHandler webSocketHandler; @Test public void run() throws Exception { @@ -67,4 +83,19 @@ public void run() throws Exception { this.thrown.expect(ExecutionException.class); wsSession.get().sendMessage(new TextMessage("a")); } + + static class Initializer + implements ApplicationContextInitializer { + + @Override + public void initialize( + ConfigurableApplicationContext configurableApplicationContext) { + TestPropertyValues + .of("spring.redis.host=" + redisContainer.getContainerIpAddress(), + "spring.redis.port=" + redisContainer.getFirstMappedPort()) + .applyTo(configurableApplicationContext.getEnvironment()); + } + + } + } diff --git a/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle b/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle index 866ccbf2a..f994813f6 100644 --- a/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle +++ b/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle @@ -17,4 +17,6 @@ dependencies { testCompile "org.assertj:assertj-core" testCompile "org.springframework:spring-test" testCompile "commons-codec:commons-codec" + + integrationTestCompile "org.testcontainers:testcontainers" } diff --git a/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java b/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java index 5d6d76912..372b06e11 100644 --- a/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java +++ b/samples/javaconfig/rest/src/integration-test/java/rest/RestMockMvcTests.java @@ -17,16 +17,22 @@ package rest; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; - -import sample.HttpSessionConfig; +import org.testcontainers.containers.GenericContainer; import sample.SecurityConfig; import sample.mvc.MvcConfig; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.session.Session; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +import org.springframework.session.web.http.HeaderHttpSessionStrategy; +import org.springframework.session.web.http.HttpSessionStrategy; import org.springframework.session.web.http.SessionRepositoryFilter; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -44,18 +50,24 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { HttpSessionConfig.class, SecurityConfig.class, +@ContextConfiguration(classes = { RestMockMvcTests.Config.class, SecurityConfig.class, MvcConfig.class }) @WebAppConfiguration public class RestMockMvcTests { + private static final String DOCKER_IMAGE = "redis:3.2.9"; + + @ClassRule + public static GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE) + .withExposedPorts(6379); + @Autowired - SessionRepositoryFilter sessionRepositoryFilter; + private SessionRepositoryFilter sessionRepositoryFilter; @Autowired - WebApplicationContext context; + private WebApplicationContext context; - MockMvc mvc; + private MockMvc mvc; @Before public void setup() { @@ -81,4 +93,21 @@ public void autheticatedRequestPostProcessor() throws Exception { .andExpect(content().string("{\"username\":\"user\"}")); } + @Configuration + @EnableRedisHttpSession + static class Config { + + @Bean + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer.getContainerIpAddress(), + redisContainer.getFirstMappedPort()); + } + + @Bean + public HttpSessionStrategy httpSessionStrategy() { + return new HeaderHttpSessionStrategy(); + } + + } + } diff --git a/spring-session-data-redis/spring-session-data-redis.gradle b/spring-session-data-redis/spring-session-data-redis.gradle index cf3e9b097..753b3e2a5 100644 --- a/spring-session-data-redis/spring-session-data-redis.gradle +++ b/spring-session-data-redis/spring-session-data-redis.gradle @@ -15,4 +15,5 @@ dependencies { integrationTestCompile "redis.clients:jedis" integrationTestCompile "org.apache.commons:commons-pool2" + integrationTestCompile "org.testcontainers:testcontainers" } diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/AbstractITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/AbstractITests.java deleted file mode 100644 index 35b9fe551..000000000 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/AbstractITests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2014-2016 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 org.springframework.session.data; - -import java.util.UUID; - -import org.junit.Before; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -/** - * Base class for repositories integration tests - * - * @author Jakub Kubrynski - */ -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -public abstract class AbstractITests { - - protected SecurityContext context; - - protected SecurityContext changedContext; - - @Autowired(required = false) - protected SessionEventRegistry registry; - - @Before - public void setup() { - if (this.registry != null) { - this.registry.clear(); - } - this.context = SecurityContextHolder.createEmptyContext(); - this.context.setAuthentication( - new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), - "na", AuthorityUtils.createAuthorityList("ROLE_USER"))); - - this.changedContext = SecurityContextHolder.createEmptyContext(); - this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken( - "changedContext-" + UUID.randomUUID(), "na", - AuthorityUtils.createAuthorityList("ROLE_USER"))); - } - -} diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/AbstractRedisITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/AbstractRedisITests.java new file mode 100644 index 000000000..3c3c5724e --- /dev/null +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/AbstractRedisITests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-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 org.springframework.session.data.redis; + +import org.junit.ClassRule; +import org.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; + +/** + * Base class for {@link RedisOperationsSessionRepository} integration tests. + * + * @author Vedran Pavic + */ +public abstract class AbstractRedisITests { + + private static final String DOCKER_IMAGE = "redis:3.2.9"; + + @ClassRule + public static GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE) + .withExposedPorts(6379); + + protected static class BaseConfig { + + @Bean + public JedisConnectionFactory connectionFactory() { + RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration( + redisContainer.getContainerIpAddress(), + redisContainer.getFirstMappedPort()); + return new JedisConnectionFactory(configuration); + } + + } + +} diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java index e32744ea6..1d9a288dd 100644 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java @@ -13,18 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.session.data.redis; import java.util.Map; import java.util.UUID; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.DefaultMessage; -import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -33,18 +35,22 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.session.Session; -import org.springframework.session.data.AbstractITests; import org.springframework.session.data.SessionEventRegistry; import org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.events.SessionCreatedEvent; import org.springframework.session.events.SessionDestroyedEvent; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; import static org.assertj.core.api.Assertions.assertThat; +@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration -public class RedisOperationsSessionRepositoryITests extends AbstractITests { +@WebAppConfiguration +public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests { + private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; private static final String INDEX_NAME = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME; @@ -53,7 +59,30 @@ public class RedisOperationsSessionRepositoryITests extends AbstractITests { private RedisOperationsSessionRepository repository; @Autowired - RedisOperations redis; + private SessionEventRegistry registry; + + @Autowired + private RedisOperations redis; + + private SecurityContext context; + + private SecurityContext changedContext; + + @Before + public void setup() { + if (this.registry != null) { + this.registry.clear(); + } + this.context = SecurityContextHolder.createEmptyContext(); + this.context.setAuthentication( + new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), + "na", AuthorityUtils.createAuthorityList("ROLE_USER"))); + + this.changedContext = SecurityContextHolder.createEmptyContext(); + this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken( + "changedContext-" + UUID.randomUUID(), "na", + AuthorityUtils.createAuthorityList("ROLE_USER"))); + } @Test public void saves() throws InterruptedException { @@ -547,15 +576,13 @@ private String getChangedSecurityName() { @Configuration @EnableRedisHttpSession(redisNamespace = "RedisOperationsSessionRepositoryITests") - static class Config { - @Bean - public JedisConnectionFactory connectionFactory() throws Exception { - return new JedisConnectionFactory(); - } + static class Config extends BaseConfig { @Bean public SessionEventRegistry sessionEventRegistry() { return new SessionEventRegistry(); } + } + } diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java index b7b04e2bb..d1feade73 100644 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java @@ -26,7 +26,6 @@ import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.AuthorityUtils; @@ -34,6 +33,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.session.Session; import org.springframework.session.SessionRepository; +import org.springframework.session.data.redis.AbstractRedisITests; import org.springframework.session.events.SessionExpiredEvent; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -44,7 +44,9 @@ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @WebAppConfiguration -public class EnableRedisHttpSessionExpireSessionDestroyedTests { +public class EnableRedisHttpSessionExpireSessionDestroyedTests + extends AbstractRedisITests { + @Autowired private SessionRepository repository; @@ -110,15 +112,13 @@ public void setLock(Object lock) { @Configuration @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1) - static class Config { - @Bean - public JedisConnectionFactory connectionFactory() throws Exception { - return new JedisConnectionFactory(); - } + static class Config extends BaseConfig { @Bean public SessionExpiredEventRegistry sessionDestroyedEventRegistry() { return new SessionExpiredEventRegistry(); } + } + } diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisHttpSessionConfig.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisHttpSessionConfig.java deleted file mode 100644 index b26ab27af..000000000 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisHttpSessionConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2014-2016 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 org.springframework.session.data.redis.flushimmediately; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; -import org.springframework.session.data.redis.RedisFlushMode; -import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; - -/** - * @author Rob Winch - * - */ -@Configuration -@EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) -public class RedisHttpSessionConfig { - @Bean - public JedisConnectionFactory connectionFactory() throws Exception { - return new JedisConnectionFactory(); - } -} diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisOperationsSessionRepositoryFlushImmediatelyITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisOperationsSessionRepositoryFlushImmediatelyITests.java index 70d6886a4..9923b1465 100644 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisOperationsSessionRepositoryFlushImmediatelyITests.java +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/flushimmediately/RedisOperationsSessionRepositoryFlushImmediatelyITests.java @@ -20,8 +20,12 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; import org.springframework.session.Session; import org.springframework.session.SessionRepository; +import org.springframework.session.data.redis.AbstractRedisITests; +import org.springframework.session.data.redis.RedisFlushMode; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -29,9 +33,10 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = RedisHttpSessionConfig.class) +@ContextConfiguration @WebAppConfiguration -public class RedisOperationsSessionRepositoryFlushImmediatelyITests { +public class RedisOperationsSessionRepositoryFlushImmediatelyITests + extends AbstractRedisITests { @Autowired private SessionRepository sessionRepository; @@ -44,4 +49,11 @@ public void savesOnCreate() throws InterruptedException { assertThat(getSession).isNotNull(); } + + @Configuration + @EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) + static class RedisHttpSessionConfig extends BaseConfig { + + } + } diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java index 78431f6ea..2ccc68d4c 100644 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/taskexecutor/RedisListenerContainerTaskExecutorITests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -28,9 +28,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.TaskExecutor; -import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.data.redis.core.RedisOperations; +import org.springframework.session.data.redis.AbstractRedisITests; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -44,13 +44,13 @@ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @WebAppConfiguration -public class RedisListenerContainerTaskExecutorITests { +public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITests { @Autowired - SessionTaskExecutor executor; + private SessionTaskExecutor executor; @Autowired - RedisOperations redis; + private RedisOperations redis; @Test public void testRedisDelEventsAreDispatchedInSessionTaskExecutor() @@ -99,21 +99,18 @@ public boolean taskDispatched() throws InterruptedException { @Configuration @EnableRedisHttpSession(redisNamespace = "RedisListenerContainerTaskExecutorITests") - static class Config { + static class Config extends BaseConfig { @Bean - JedisConnectionFactory connectionFactory() throws Exception { - return new JedisConnectionFactory(); - } - - @Bean - Executor springSessionRedisTaskExecutor() { + public Executor springSessionRedisTaskExecutor() { return new SessionTaskExecutor(Executors.newSingleThreadExecutor()); } @Bean - Executor springSessionRedisSubscriptionExecutor() { + public Executor springSessionRedisSubscriptionExecutor() { return new SimpleAsyncTaskExecutor(); } + } + } diff --git a/spring-session-jdbc/spring-session-jdbc.gradle b/spring-session-jdbc/spring-session-jdbc.gradle index 74e0959f6..1c9f3ec21 100644 --- a/spring-session-jdbc/spring-session-jdbc.gradle +++ b/spring-session-jdbc/spring-session-jdbc.gradle @@ -11,7 +11,13 @@ dependencies { testCompile "org.springframework:spring-web" testCompile "org.springframework.security:spring-security-core" - integrationTestCompile "org.apache.derby:derby" integrationTestCompile "com.h2database:h2" + integrationTestCompile "mysql:mysql-connector-java" + integrationTestCompile "org.apache.derby:derby" integrationTestCompile "org.hsqldb:hsqldb" + integrationTestCompile "org.mariadb.jdbc:mariadb-java-client" + integrationTestCompile "org.postgresql:postgresql" + integrationTestCompile "org.testcontainers:mariadb" + integrationTestCompile "org.testcontainers:mysql" + integrationTestCompile "org.testcontainers:postgresql" } diff --git a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java index 91a362b6a..6a55d7613 100644 --- a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java +++ b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java @@ -26,7 +26,6 @@ import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -40,9 +39,6 @@ import org.springframework.session.MapSession; import org.springframework.session.Session; import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; @@ -54,9 +50,6 @@ * @author Vedran Pavic * @since 1.2.0 */ -@WebAppConfiguration -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) public abstract class AbstractJdbcOperationsSessionRepositoryITests { private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; diff --git a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB10JdbcOperationsSessionRepositoryITests.java b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB10JdbcOperationsSessionRepositoryITests.java new file mode 100644 index 000000000..21857cba8 --- /dev/null +++ b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB10JdbcOperationsSessionRepositoryITests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2014-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 org.springframework.session.jdbc; + +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.junit.ClassRule; +import org.junit.runner.RunWith; +import org.mariadb.jdbc.MariaDbDataSource; +import org.testcontainers.containers.MariaDBContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +/** + * Integration tests for {@link JdbcOperationsSessionRepository} using MariaDB 10.x + * database. + * + * @author Vedran Pavic + */ +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration +public class MariaDB10JdbcOperationsSessionRepositoryITests + extends AbstractJdbcOperationsSessionRepositoryITests { + + private static final String DOCKER_IMAGE = "mariadb:10.2.7"; + + @ClassRule + public static MariaDBContainer mariaDBContainer = new MariaDBContainer(DOCKER_IMAGE); + + @Configuration + static class Config extends BaseConfig { + + @Bean + public DataSource dataSource() throws SQLException { + MariaDbDataSource dataSource = new MariaDbDataSource( + mariaDBContainer.getJdbcUrl()); + dataSource.setUserName(mariaDBContainer.getUsername()); + dataSource.setPassword(mariaDBContainer.getPassword()); + return dataSource; + } + + @Bean + public DataSourceInitializer initializer(DataSource dataSource, + ResourceLoader resourceLoader) { + DataSourceInitializer initializer = new DataSourceInitializer(); + initializer.setDataSource(dataSource); + initializer.setDatabasePopulator( + new ResourceDatabasePopulator(resourceLoader.getResource( + "classpath:org/springframework/session/jdbc/schema-mysql.sql"))); + return initializer; + } + + } + +} diff --git a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB5JdbcOperationsSessionRepositoryITests.java b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB5JdbcOperationsSessionRepositoryITests.java new file mode 100644 index 000000000..8df35af4f --- /dev/null +++ b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MariaDB5JdbcOperationsSessionRepositoryITests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2014-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 org.springframework.session.jdbc; + +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.junit.ClassRule; +import org.junit.runner.RunWith; +import org.mariadb.jdbc.MariaDbDataSource; +import org.testcontainers.containers.MariaDBContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +/** + * Integration tests for {@link JdbcOperationsSessionRepository} using MariaDB 5.x + * database. + * + * @author Vedran Pavic + */ +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration +public class MariaDB5JdbcOperationsSessionRepositoryITests + extends AbstractJdbcOperationsSessionRepositoryITests { + + private static final String DOCKER_IMAGE = "mariadb:5.5.56"; + + @ClassRule + public static MariaDBContainer mariaDBContainer = new MariaDBContainer(DOCKER_IMAGE); + + @Configuration + static class Config extends BaseConfig { + + @Bean + public DataSource dataSource() throws SQLException { + MariaDbDataSource dataSource = new MariaDbDataSource( + mariaDBContainer.getJdbcUrl()); + dataSource.setUserName(mariaDBContainer.getUsername()); + dataSource.setPassword(mariaDBContainer.getPassword()); + return dataSource; + } + + @Bean + public DataSourceInitializer initializer(DataSource dataSource, + ResourceLoader resourceLoader) { + DataSourceInitializer initializer = new DataSourceInitializer(); + initializer.setDataSource(dataSource); + initializer.setDatabasePopulator( + new ResourceDatabasePopulator(resourceLoader.getResource( + "classpath:org/springframework/session/jdbc/schema-mysql.sql"))); + return initializer; + } + + } + +} diff --git a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MySQL5JdbcOperationsSessionRepositoryITests.java b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MySQL5JdbcOperationsSessionRepositoryITests.java new file mode 100644 index 000000000..5d67c8137 --- /dev/null +++ b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/MySQL5JdbcOperationsSessionRepositoryITests.java @@ -0,0 +1,76 @@ +/* + * Copyright 2014-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 org.springframework.session.jdbc; + +import javax.sql.DataSource; + +import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; +import org.junit.ClassRule; +import org.junit.runner.RunWith; +import org.testcontainers.containers.MySQLContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +/** + * Integration tests for {@link JdbcOperationsSessionRepository} using MySQL 5.x database. + * + * @author Vedran Pavic + */ +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration +public class MySQL5JdbcOperationsSessionRepositoryITests + extends AbstractJdbcOperationsSessionRepositoryITests { + + private static final String DOCKER_IMAGE = "mysql:5.7.18"; + + @ClassRule + public static MySQLContainer mySQLContainer = new MySQLContainer(DOCKER_IMAGE); + + @Configuration + static class Config extends BaseConfig { + + @Bean + public DataSource dataSource() { + MysqlDataSource dataSource = new MysqlDataSource(); + dataSource.setUrl(mySQLContainer.getJdbcUrl()); + dataSource.setUser(mySQLContainer.getUsername()); + dataSource.setPassword(mySQLContainer.getPassword()); + return dataSource; + } + + @Bean + public DataSourceInitializer initializer(DataSource dataSource, + ResourceLoader resourceLoader) { + DataSourceInitializer initializer = new DataSourceInitializer(); + initializer.setDataSource(dataSource); + initializer.setDatabasePopulator( + new ResourceDatabasePopulator(resourceLoader.getResource( + "classpath:org/springframework/session/jdbc/schema-mysql.sql"))); + return initializer; + } + + } + +} diff --git a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/PostgreSQL9JdbcOperationsSessionRepositoryITests.java b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/PostgreSQL9JdbcOperationsSessionRepositoryITests.java new file mode 100644 index 000000000..de8dcb4b4 --- /dev/null +++ b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/PostgreSQL9JdbcOperationsSessionRepositoryITests.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014-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 org.springframework.session.jdbc; + +import javax.sql.DataSource; + +import org.junit.ClassRule; +import org.junit.runner.RunWith; +import org.postgresql.ds.PGSimpleDataSource; +import org.testcontainers.containers.PostgreSQLContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +/** + * Integration tests for {@link JdbcOperationsSessionRepository} using PostgreSQL + * database. + * + * @author Vedran Pavic + */ +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration +public class PostgreSQL9JdbcOperationsSessionRepositoryITests + extends AbstractJdbcOperationsSessionRepositoryITests { + + private static final String DOCKER_IMAGE = "postgres:9.6.3"; + + @ClassRule + public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer( + DOCKER_IMAGE); + + @Configuration + static class Config extends BaseConfig { + + @Bean + public DataSource dataSource() { + PGSimpleDataSource dataSource = new PGSimpleDataSource(); + dataSource.setUrl(postgreSQLContainer.getJdbcUrl()); + dataSource.setUser(postgreSQLContainer.getUsername()); + dataSource.setPassword(postgreSQLContainer.getPassword()); + return dataSource; + } + + @Bean + public DataSourceInitializer initializer(DataSource dataSource, + ResourceLoader resourceLoader) { + DataSourceInitializer initializer = new DataSourceInitializer(); + initializer.setDataSource(dataSource); + initializer.setDatabasePopulator( + new ResourceDatabasePopulator(resourceLoader.getResource( + "classpath:org/springframework/session/jdbc/schema-postgresql.sql"))); + return initializer; + } + + } + +} From cf5bf78c922a6afb0e3cbdb7844a3644be37a039 Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Thu, 15 Jun 2017 19:45:11 +0200 Subject: [PATCH 2/3] Use TestContainers for Gretty integration tests --- ...ion-sample-javaconfig-custom-cookie.gradle | 5 ++ .../src/main/java/sample/Config.java | 4 +- .../main/java/sample/EmbeddedRedisConfig.java | 59 +++++++++++++++++++ ...ing-session-sample-javaconfig-redis.gradle | 5 ++ .../redis/src/main/java/sample/Config.java | 4 +- .../main/java/sample/EmbeddedRedisConfig.java | 59 +++++++++++++++++++ ...ring-session-sample-javaconfig-rest.gradle | 5 ++ .../main/java/sample/EmbeddedRedisConfig.java | 59 +++++++++++++++++++ .../main/java/sample/HttpSessionConfig.java | 4 +- ...-session-sample-javaconfig-security.gradle | 5 ++ .../security/src/main/java/sample/Config.java | 4 +- .../main/java/sample/EmbeddedRedisConfig.java | 59 +++++++++++++++++++ ...ing-session-sample-javaconfig-users.gradle | 5 ++ .../users/src/main/java/sample/Config.java | 5 +- .../main/java/sample/EmbeddedRedisConfig.java | 59 +++++++++++++++++++ .../spring-session-sample-xml-redis.gradle | 5 ++ .../main/java/sample/EmbeddedRedisConfig.java | 59 +++++++++++++++++++ .../main/webapp/WEB-INF/spring/session.xml | 5 +- 18 files changed, 403 insertions(+), 7 deletions(-) create mode 100644 samples/javaconfig/custom-cookie/src/main/java/sample/EmbeddedRedisConfig.java create mode 100644 samples/javaconfig/redis/src/main/java/sample/EmbeddedRedisConfig.java create mode 100644 samples/javaconfig/rest/src/main/java/sample/EmbeddedRedisConfig.java create mode 100644 samples/javaconfig/security/src/main/java/sample/EmbeddedRedisConfig.java create mode 100644 samples/javaconfig/users/src/main/java/sample/EmbeddedRedisConfig.java create mode 100644 samples/xml/redis/src/main/java/sample/EmbeddedRedisConfig.java diff --git a/samples/javaconfig/custom-cookie/spring-session-sample-javaconfig-custom-cookie.gradle b/samples/javaconfig/custom-cookie/spring-session-sample-javaconfig-custom-cookie.gradle index 731df52be..7e38f8afc 100644 --- a/samples/javaconfig/custom-cookie/spring-session-sample-javaconfig-custom-cookie.gradle +++ b/samples/javaconfig/custom-cookie/spring-session-sample-javaconfig-custom-cookie.gradle @@ -8,6 +8,7 @@ dependencies { compile "org.webjars:webjars-taglib" compile jstlDependencies compile slf4jDependencies + compile "org.testcontainers:testcontainers" providedCompile "javax.servlet:javax.servlet-api" @@ -16,3 +17,7 @@ dependencies { integrationTestCompile seleniumDependencies } + +gretty { + jvmArgs = ['-Dspring.profiles.active=embedded-redis'] +} diff --git a/samples/javaconfig/custom-cookie/src/main/java/sample/Config.java b/samples/javaconfig/custom-cookie/src/main/java/sample/Config.java index 92bff82f9..25b18d3f8 100644 --- a/samples/javaconfig/custom-cookie/src/main/java/sample/Config.java +++ b/samples/javaconfig/custom-cookie/src/main/java/sample/Config.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -17,11 +17,13 @@ package sample; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.web.http.CookieSerializer; import org.springframework.session.web.http.DefaultCookieSerializer; +@Import(EmbeddedRedisConfig.class) @EnableRedisHttpSession public class Config { diff --git a/samples/javaconfig/custom-cookie/src/main/java/sample/EmbeddedRedisConfig.java b/samples/javaconfig/custom-cookie/src/main/java/sample/EmbeddedRedisConfig.java new file mode 100644 index 000000000..4e8af65c3 --- /dev/null +++ b/samples/javaconfig/custom-cookie/src/main/java/sample/EmbeddedRedisConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.io.IOException; + +import org.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; + +@Configuration +@Profile("embedded-redis") +public class EmbeddedRedisConfig { + + private static final String REDIS_DOCKER_IMAGE = "redis:3.2.9"; + + @Bean(initMethod = "start") + public GenericContainer redisContainer() { + return new GenericContainer(REDIS_DOCKER_IMAGE) { + + @Override + public void close() { + super.close(); + try { + this.dockerClient.close(); + } + catch (IOException ignored) { + } + } + + }.withExposedPorts(6379); + } + + @Bean + @Primary + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(), + redisContainer().getFirstMappedPort()); + } + +} diff --git a/samples/javaconfig/redis/spring-session-sample-javaconfig-redis.gradle b/samples/javaconfig/redis/spring-session-sample-javaconfig-redis.gradle index 731df52be..7e38f8afc 100644 --- a/samples/javaconfig/redis/spring-session-sample-javaconfig-redis.gradle +++ b/samples/javaconfig/redis/spring-session-sample-javaconfig-redis.gradle @@ -8,6 +8,7 @@ dependencies { compile "org.webjars:webjars-taglib" compile jstlDependencies compile slf4jDependencies + compile "org.testcontainers:testcontainers" providedCompile "javax.servlet:javax.servlet-api" @@ -16,3 +17,7 @@ dependencies { integrationTestCompile seleniumDependencies } + +gretty { + jvmArgs = ['-Dspring.profiles.active=embedded-redis'] +} diff --git a/samples/javaconfig/redis/src/main/java/sample/Config.java b/samples/javaconfig/redis/src/main/java/sample/Config.java index 4a03dd74a..69f8b94fb 100644 --- a/samples/javaconfig/redis/src/main/java/sample/Config.java +++ b/samples/javaconfig/redis/src/main/java/sample/Config.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -17,9 +17,11 @@ package sample; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +@Import(EmbeddedRedisConfig.class) // tag::class[] @EnableRedisHttpSession // <1> public class Config { diff --git a/samples/javaconfig/redis/src/main/java/sample/EmbeddedRedisConfig.java b/samples/javaconfig/redis/src/main/java/sample/EmbeddedRedisConfig.java new file mode 100644 index 000000000..4e8af65c3 --- /dev/null +++ b/samples/javaconfig/redis/src/main/java/sample/EmbeddedRedisConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.io.IOException; + +import org.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; + +@Configuration +@Profile("embedded-redis") +public class EmbeddedRedisConfig { + + private static final String REDIS_DOCKER_IMAGE = "redis:3.2.9"; + + @Bean(initMethod = "start") + public GenericContainer redisContainer() { + return new GenericContainer(REDIS_DOCKER_IMAGE) { + + @Override + public void close() { + super.close(); + try { + this.dockerClient.close(); + } + catch (IOException ignored) { + } + } + + }.withExposedPorts(6379); + } + + @Bean + @Primary + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(), + redisContainer().getFirstMappedPort()); + } + +} diff --git a/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle b/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle index f994813f6..819575c66 100644 --- a/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle +++ b/samples/javaconfig/rest/spring-session-sample-javaconfig-rest.gradle @@ -9,6 +9,7 @@ dependencies { compile "com.fasterxml.jackson.core:jackson-databind" compile jstlDependencies compile slf4jDependencies + compile "org.testcontainers:testcontainers" providedCompile "javax.servlet:javax.servlet-api" @@ -20,3 +21,7 @@ dependencies { integrationTestCompile "org.testcontainers:testcontainers" } + +gretty { + jvmArgs = ['-Dspring.profiles.active=embedded-redis'] +} diff --git a/samples/javaconfig/rest/src/main/java/sample/EmbeddedRedisConfig.java b/samples/javaconfig/rest/src/main/java/sample/EmbeddedRedisConfig.java new file mode 100644 index 000000000..4e8af65c3 --- /dev/null +++ b/samples/javaconfig/rest/src/main/java/sample/EmbeddedRedisConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.io.IOException; + +import org.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; + +@Configuration +@Profile("embedded-redis") +public class EmbeddedRedisConfig { + + private static final String REDIS_DOCKER_IMAGE = "redis:3.2.9"; + + @Bean(initMethod = "start") + public GenericContainer redisContainer() { + return new GenericContainer(REDIS_DOCKER_IMAGE) { + + @Override + public void close() { + super.close(); + try { + this.dockerClient.close(); + } + catch (IOException ignored) { + } + } + + }.withExposedPorts(6379); + } + + @Bean + @Primary + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(), + redisContainer().getFirstMappedPort()); + } + +} diff --git a/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java b/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java index 5fc10a6c6..80fd9c7cf 100644 --- a/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java +++ b/samples/javaconfig/rest/src/main/java/sample/HttpSessionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -18,11 +18,13 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.web.http.HeaderHttpSessionStrategy; import org.springframework.session.web.http.HttpSessionStrategy; +@Import(EmbeddedRedisConfig.class) // tag::class[] @Configuration @EnableRedisHttpSession // <1> diff --git a/samples/javaconfig/security/spring-session-sample-javaconfig-security.gradle b/samples/javaconfig/security/spring-session-sample-javaconfig-security.gradle index 82c3da0ba..fa4e092ae 100644 --- a/samples/javaconfig/security/spring-session-sample-javaconfig-security.gradle +++ b/samples/javaconfig/security/spring-session-sample-javaconfig-security.gradle @@ -10,6 +10,7 @@ dependencies { compile "org.webjars:webjars-taglib" compile jstlDependencies compile slf4jDependencies + compile "org.testcontainers:testcontainers" providedCompile "javax.servlet:javax.servlet-api" providedCompile "javax.servlet.jsp:javax.servlet.jsp-api" @@ -20,3 +21,7 @@ dependencies { integrationTestCompile seleniumDependencies } + +gretty { + jvmArgs = ['-Dspring.profiles.active=embedded-redis'] +} diff --git a/samples/javaconfig/security/src/main/java/sample/Config.java b/samples/javaconfig/security/src/main/java/sample/Config.java index 384e090ad..660c2ed03 100644 --- a/samples/javaconfig/security/src/main/java/sample/Config.java +++ b/samples/javaconfig/security/src/main/java/sample/Config.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -18,9 +18,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +@Import(EmbeddedRedisConfig.class) // tag::class[] @Configuration @EnableRedisHttpSession // <1> diff --git a/samples/javaconfig/security/src/main/java/sample/EmbeddedRedisConfig.java b/samples/javaconfig/security/src/main/java/sample/EmbeddedRedisConfig.java new file mode 100644 index 000000000..4e8af65c3 --- /dev/null +++ b/samples/javaconfig/security/src/main/java/sample/EmbeddedRedisConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.io.IOException; + +import org.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; + +@Configuration +@Profile("embedded-redis") +public class EmbeddedRedisConfig { + + private static final String REDIS_DOCKER_IMAGE = "redis:3.2.9"; + + @Bean(initMethod = "start") + public GenericContainer redisContainer() { + return new GenericContainer(REDIS_DOCKER_IMAGE) { + + @Override + public void close() { + super.close(); + try { + this.dockerClient.close(); + } + catch (IOException ignored) { + } + } + + }.withExposedPorts(6379); + } + + @Bean + @Primary + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(), + redisContainer().getFirstMappedPort()); + } + +} diff --git a/samples/javaconfig/users/spring-session-sample-javaconfig-users.gradle b/samples/javaconfig/users/spring-session-sample-javaconfig-users.gradle index c42839000..46d6c4f9b 100644 --- a/samples/javaconfig/users/spring-session-sample-javaconfig-users.gradle +++ b/samples/javaconfig/users/spring-session-sample-javaconfig-users.gradle @@ -8,6 +8,7 @@ dependencies { compile "org.webjars:webjars-taglib" compile jstlDependencies compile slf4jDependencies + compile "org.testcontainers:testcontainers" providedCompile "javax.servlet:javax.servlet-api" @@ -17,3 +18,7 @@ dependencies { integrationTestCompile seleniumDependencies } + +gretty { + jvmArgs = ['-Dspring.profiles.active=embedded-redis'] +} diff --git a/samples/javaconfig/users/src/main/java/sample/Config.java b/samples/javaconfig/users/src/main/java/sample/Config.java index 2356e748a..6fc53cdde 100644 --- a/samples/javaconfig/users/src/main/java/sample/Config.java +++ b/samples/javaconfig/users/src/main/java/sample/Config.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-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. @@ -18,13 +18,14 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; /** * @author Rob Winch */ - +@Import(EmbeddedRedisConfig.class) // tag::class[] @Configuration @EnableRedisHttpSession diff --git a/samples/javaconfig/users/src/main/java/sample/EmbeddedRedisConfig.java b/samples/javaconfig/users/src/main/java/sample/EmbeddedRedisConfig.java new file mode 100644 index 000000000..4e8af65c3 --- /dev/null +++ b/samples/javaconfig/users/src/main/java/sample/EmbeddedRedisConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.io.IOException; + +import org.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; + +@Configuration +@Profile("embedded-redis") +public class EmbeddedRedisConfig { + + private static final String REDIS_DOCKER_IMAGE = "redis:3.2.9"; + + @Bean(initMethod = "start") + public GenericContainer redisContainer() { + return new GenericContainer(REDIS_DOCKER_IMAGE) { + + @Override + public void close() { + super.close(); + try { + this.dockerClient.close(); + } + catch (IOException ignored) { + } + } + + }.withExposedPorts(6379); + } + + @Bean + @Primary + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(), + redisContainer().getFirstMappedPort()); + } + +} diff --git a/samples/xml/redis/spring-session-sample-xml-redis.gradle b/samples/xml/redis/spring-session-sample-xml-redis.gradle index 731df52be..7e38f8afc 100644 --- a/samples/xml/redis/spring-session-sample-xml-redis.gradle +++ b/samples/xml/redis/spring-session-sample-xml-redis.gradle @@ -8,6 +8,7 @@ dependencies { compile "org.webjars:webjars-taglib" compile jstlDependencies compile slf4jDependencies + compile "org.testcontainers:testcontainers" providedCompile "javax.servlet:javax.servlet-api" @@ -16,3 +17,7 @@ dependencies { integrationTestCompile seleniumDependencies } + +gretty { + jvmArgs = ['-Dspring.profiles.active=embedded-redis'] +} diff --git a/samples/xml/redis/src/main/java/sample/EmbeddedRedisConfig.java b/samples/xml/redis/src/main/java/sample/EmbeddedRedisConfig.java new file mode 100644 index 000000000..4e8af65c3 --- /dev/null +++ b/samples/xml/redis/src/main/java/sample/EmbeddedRedisConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.io.IOException; + +import org.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; + +@Configuration +@Profile("embedded-redis") +public class EmbeddedRedisConfig { + + private static final String REDIS_DOCKER_IMAGE = "redis:3.2.9"; + + @Bean(initMethod = "start") + public GenericContainer redisContainer() { + return new GenericContainer(REDIS_DOCKER_IMAGE) { + + @Override + public void close() { + super.close(); + try { + this.dockerClient.close(); + } + catch (IOException ignored) { + } + } + + }.withExposedPorts(6379); + } + + @Bean + @Primary + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(), + redisContainer().getFirstMappedPort()); + } + +} diff --git a/samples/xml/redis/src/main/webapp/WEB-INF/spring/session.xml b/samples/xml/redis/src/main/webapp/WEB-INF/spring/session.xml index 4b569357a..62f9b2460 100644 --- a/samples/xml/redis/src/main/webapp/WEB-INF/spring/session.xml +++ b/samples/xml/redis/src/main/webapp/WEB-INF/spring/session.xml @@ -15,4 +15,7 @@ - \ No newline at end of file + + + + From 4b8582afd89bcb0d25ab19b052479929f28e2904 Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Thu, 20 Jul 2017 15:19:12 +0200 Subject: [PATCH 3/3] Update guides for Redis based samples --- docs/src/docs/asciidoc/guides/boot-findbyusername.adoc | 1 + docs/src/docs/asciidoc/guides/boot-redis.adoc | 1 + docs/src/docs/asciidoc/guides/boot-websocket.adoc | 1 + docs/src/docs/asciidoc/guides/grails3.adoc | 1 + docs/src/docs/asciidoc/guides/java-custom-cookie.adoc | 1 + docs/src/docs/asciidoc/guides/java-redis.adoc | 1 + docs/src/docs/asciidoc/guides/java-rest.adoc | 1 + docs/src/docs/asciidoc/guides/java-security.adoc | 1 + docs/src/docs/asciidoc/guides/java-users.adoc | 1 + docs/src/docs/asciidoc/guides/xml-redis.adoc | 1 + 10 files changed, 10 insertions(+) diff --git a/docs/src/docs/asciidoc/guides/boot-findbyusername.adoc b/docs/src/docs/asciidoc/guides/boot-findbyusername.adoc index b233e5e6f..c2feb2e48 100644 --- a/docs/src/docs/asciidoc/guides/boot-findbyusername.adoc +++ b/docs/src/docs/asciidoc/guides/boot-findbyusername.adoc @@ -110,6 +110,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `JedisConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/boot-redis.adoc b/docs/src/docs/asciidoc/guides/boot-redis.adoc index c270d3e49..6a0699f18 100644 --- a/docs/src/docs/asciidoc/guides/boot-redis.adoc +++ b/docs/src/docs/asciidoc/guides/boot-redis.adoc @@ -93,6 +93,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `JedisConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/boot-websocket.adoc b/docs/src/docs/asciidoc/guides/boot-websocket.adoc index 52ef555dd..f556dda57 100644 --- a/docs/src/docs/asciidoc/guides/boot-websocket.adoc +++ b/docs/src/docs/asciidoc/guides/boot-websocket.adoc @@ -85,6 +85,7 @@ server.session.timeout=60 ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `LettuceConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/grails3.adoc b/docs/src/docs/asciidoc/guides/grails3.adoc index 30b31e783..5e7d3f0a4 100644 --- a/docs/src/docs/asciidoc/guides/grails3.adoc +++ b/docs/src/docs/asciidoc/guides/grails3.adoc @@ -86,6 +86,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `JedisConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/java-custom-cookie.adoc b/docs/src/docs/asciidoc/guides/java-custom-cookie.adoc index ddca7f0e9..08b01334e 100644 --- a/docs/src/docs/asciidoc/guides/java-custom-cookie.adoc +++ b/docs/src/docs/asciidoc/guides/java-custom-cookie.adoc @@ -80,6 +80,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `LettuceConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/java-redis.adoc b/docs/src/docs/asciidoc/guides/java-redis.adoc index b47fcf398..7f05b785b 100644 --- a/docs/src/docs/asciidoc/guides/java-redis.adoc +++ b/docs/src/docs/asciidoc/guides/java-redis.adoc @@ -127,6 +127,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `LettuceConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/java-rest.adoc b/docs/src/docs/asciidoc/guides/java-rest.adoc index aa25d9918..3c6f47d99 100644 --- a/docs/src/docs/asciidoc/guides/java-rest.adoc +++ b/docs/src/docs/asciidoc/guides/java-rest.adoc @@ -128,6 +128,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `LettuceConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/java-security.adoc b/docs/src/docs/asciidoc/guides/java-security.adoc index 7187b4e66..e3aca3578 100644 --- a/docs/src/docs/asciidoc/guides/java-security.adoc +++ b/docs/src/docs/asciidoc/guides/java-security.adoc @@ -132,6 +132,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `LettuceConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/java-users.adoc b/docs/src/docs/asciidoc/guides/java-users.adoc index 334ce19f9..1871dcb25 100644 --- a/docs/src/docs/asciidoc/guides/java-users.adoc +++ b/docs/src/docs/asciidoc/guides/java-users.adoc @@ -21,6 +21,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `LettuceConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ---- diff --git a/docs/src/docs/asciidoc/guides/xml-redis.adoc b/docs/src/docs/asciidoc/guides/xml-redis.adoc index 6581e6af1..d4b18b23e 100644 --- a/docs/src/docs/asciidoc/guides/xml-redis.adoc +++ b/docs/src/docs/asciidoc/guides/xml-redis.adoc @@ -135,6 +135,7 @@ You can run the sample by obtaining the {download-url}[source code] and invoking ==== For the sample to work, you must http://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379). Alternatively, you can update the `LettuceConnectionFactory` to point to a Redis server. +Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions. ==== ----