Skip to content

Commit 108b331

Browse files
Merge branch '2.6.x' into 2.7.x
Closes gh-30889
2 parents 833e3ae + b0bedc3 commit 108b331

File tree

11 files changed

+232
-39
lines changed

11 files changed

+232
-39
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
plugins {
2+
id "java"
3+
id "org.springframework.boot.conventions"
4+
}
5+
6+
description = "Spring Boot Session WebFlux MongoDB smoke test"
7+
8+
dependencies {
9+
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security"))
10+
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux"))
11+
12+
runtimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-mongodb-reactive"))
13+
runtimeOnly("org.springframework.session:spring-session-data-mongodb")
14+
15+
testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
16+
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
17+
testImplementation("org.testcontainers:mongodb")
18+
testImplementation("org.testcontainers:testcontainers")
19+
testImplementation("org.testcontainers:junit-jupiter")
20+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,10 +24,10 @@
2424
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
2525

2626
@SpringBootApplication
27-
public class SampleSessionWebFluxApplication {
27+
public class SampleSessionWebFluxMongoApplication {
2828

2929
public static void main(String[] args) {
30-
SpringApplication.run(SampleSessionWebFluxApplication.class);
30+
SpringApplication.run(SampleSessionWebFluxMongoApplication.class);
3131
}
3232

3333
@Bean
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
spring.security.user.name=user
22
spring.security.user.password=password
3-
spring.mongodb.embedded.version=3.5.5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package smoketest.session;
18+
19+
import java.time.Duration;
20+
import java.util.Base64;
21+
22+
import org.junit.jupiter.api.Test;
23+
import org.testcontainers.containers.MongoDBContainer;
24+
import org.testcontainers.junit.jupiter.Container;
25+
import org.testcontainers.junit.jupiter.Testcontainers;
26+
import reactor.util.function.Tuples;
27+
28+
import org.springframework.beans.factory.annotation.Autowired;
29+
import org.springframework.boot.test.context.SpringBootTest;
30+
import org.springframework.boot.test.web.server.LocalServerPort;
31+
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
32+
import org.springframework.http.HttpStatus;
33+
import org.springframework.test.context.DynamicPropertyRegistry;
34+
import org.springframework.test.context.DynamicPropertySource;
35+
import org.springframework.web.reactive.function.client.WebClient;
36+
37+
import static org.assertj.core.api.Assertions.assertThat;
38+
39+
/**
40+
* Integration tests for {@link SampleSessionWebFluxMongoApplication}.
41+
*
42+
* @author Vedran Pavic
43+
* @author Scott Frederick
44+
*/
45+
@SpringBootTest(properties = "spring.session.timeout:10", webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
46+
@Testcontainers(disabledWithoutDocker = true)
47+
class SampleSessionWebFluxMongoApplicationTests {
48+
49+
@Container
50+
private static final MongoDBContainer mongo = new MongoDBContainer(DockerImageNames.mongo()).withStartupAttempts(3)
51+
.withStartupTimeout(Duration.ofMinutes(2));
52+
53+
@LocalServerPort
54+
private int port;
55+
56+
@Autowired
57+
private WebClient.Builder webClientBuilder;
58+
59+
@DynamicPropertySource
60+
static void applicationProperties(DynamicPropertyRegistry registry) {
61+
registry.add("spring.data.mongodb.uri", mongo::getReplicaSetUrl);
62+
}
63+
64+
@Test
65+
void userDefinedMappingsSecureByDefault() {
66+
WebClient client = this.webClientBuilder.baseUrl("http://localhost:" + this.port + "/").build();
67+
client.get().header("Authorization", getBasicAuth()).exchangeToMono((response) -> {
68+
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
69+
return response.bodyToMono(String.class)
70+
.map((sessionId) -> Tuples.of(response.cookies().getFirst("SESSION").getValue(), sessionId));
71+
}).flatMap((tuple) -> {
72+
String sessionCookie = tuple.getT1();
73+
return client.get().cookie("SESSION", sessionCookie).exchangeToMono((response) -> {
74+
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
75+
return response.bodyToMono(String.class)
76+
.doOnNext((sessionId) -> assertThat(sessionId).isEqualTo(tuple.getT2()))
77+
.thenReturn(sessionCookie);
78+
});
79+
}).delayElement(Duration.ofSeconds(10))
80+
.flatMap((sessionCookie) -> client.get().cookie("SESSION", sessionCookie).exchangeToMono((response) -> {
81+
assertThat(response.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
82+
return response.releaseBody();
83+
})).block(Duration.ofSeconds(30));
84+
}
85+
86+
private String getBasicAuth() {
87+
return "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes());
88+
}
89+
90+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
plugins {
2+
id "java"
3+
id "org.springframework.boot.conventions"
4+
}
5+
6+
description = "Spring Boot Session WebFlux Redis smoke test"
7+
8+
dependencies {
9+
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security"))
10+
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux"))
11+
12+
runtimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-redis-reactive"))
13+
runtimeOnly("org.springframework.session:spring-session-data-redis")
14+
15+
testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
16+
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
17+
testImplementation("org.testcontainers:testcontainers")
18+
testImplementation("org.testcontainers:junit-jupiter")
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package smoketest.session;
18+
19+
import org.springframework.web.bind.annotation.GetMapping;
20+
import org.springframework.web.bind.annotation.RestController;
21+
import org.springframework.web.server.WebSession;
22+
23+
@RestController
24+
public class HelloRestController {
25+
26+
@GetMapping("/")
27+
String sessionId(WebSession session) {
28+
return session.getId();
29+
}
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package smoketest.session;
18+
19+
import org.springframework.boot.SpringApplication;
20+
import org.springframework.boot.autoconfigure.SpringBootApplication;
21+
import org.springframework.context.annotation.Bean;
22+
import org.springframework.security.config.web.server.ServerHttpSecurity;
23+
import org.springframework.security.web.server.SecurityWebFilterChain;
24+
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
25+
26+
@SpringBootApplication
27+
public class SampleSessionWebFluxRedisApplication {
28+
29+
public static void main(String[] args) {
30+
SpringApplication.run(SampleSessionWebFluxRedisApplication.class);
31+
}
32+
33+
@Bean
34+
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
35+
// @formatter:off
36+
return http
37+
.authorizeExchange()
38+
.anyExchange().authenticated()
39+
.and()
40+
.httpBasic().securityContextRepository(new WebSessionServerSecurityContextRepository())
41+
.and()
42+
.formLogin()
43+
.and()
44+
.build();
45+
// @formatter:on
46+
}
47+
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
spring.security.user.name=user
2+
spring.security.user.password=password
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,46 @@
2020
import java.util.Base64;
2121

2222
import org.junit.jupiter.api.Test;
23-
import org.junit.jupiter.api.condition.OS;
23+
import org.testcontainers.junit.jupiter.Container;
24+
import org.testcontainers.junit.jupiter.Testcontainers;
2425
import reactor.util.function.Tuples;
2526

2627
import org.springframework.beans.factory.annotation.Autowired;
2728
import org.springframework.boot.test.context.SpringBootTest;
2829
import org.springframework.boot.test.web.server.LocalServerPort;
29-
import org.springframework.boot.testsupport.junit.DisabledOnOs;
30+
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
3031
import org.springframework.http.HttpStatus;
32+
import org.springframework.test.context.DynamicPropertyRegistry;
33+
import org.springframework.test.context.DynamicPropertySource;
3134
import org.springframework.web.reactive.function.client.WebClient;
3235

3336
import static org.assertj.core.api.Assertions.assertThat;
3437

3538
/**
36-
* Integration tests for {@link SampleSessionWebFluxApplication}.
39+
* Integration tests for {@link SampleSessionWebFluxRedisApplication}.
3740
*
3841
* @author Vedran Pavic
42+
* @author Scott Frederick
3943
*/
4044
@SpringBootTest(properties = "spring.session.timeout:10", webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
41-
@DisabledOnOs(os = OS.LINUX, architecture = "aarch64",
42-
disabledReason = "Embedded Mongo doesn't support Linux aarch64, see https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/issues/379")
43-
class SampleSessionWebFluxApplicationTests {
45+
@Testcontainers(disabledWithoutDocker = true)
46+
class SampleSessionWebFluxRedisApplicationTests {
47+
48+
@Container
49+
private static final RedisContainer redis = new RedisContainer();
4450

4551
@LocalServerPort
4652
private int port;
4753

4854
@Autowired
4955
private WebClient.Builder webClientBuilder;
5056

57+
@DynamicPropertySource
58+
static void applicationProperties(DynamicPropertyRegistry registry) {
59+
registry.add("spring.redis.host", redis::getHost);
60+
registry.add("spring.redis.port", redis::getFirstMappedPort);
61+
}
62+
5163
@Test
5264
void userDefinedMappingsSecureByDefault() {
5365
WebClient client = this.webClientBuilder.baseUrl("http://localhost:" + this.port + "/").build();

spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-session-webflux/build.gradle

-28
This file was deleted.

0 commit comments

Comments
 (0)