Skip to content

Commit 46d1205

Browse files
elliedorieleftherias
authored andcommitted
Create sample Spring Boot / Hazelcast project
Closes gh-1647
1 parent cc85e92 commit 46d1205

File tree

16 files changed

+598
-0
lines changed

16 files changed

+598
-0
lines changed

spring-session-docs/src/docs/asciidoc/index.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ To get started with Spring Session, the best place to start is our Sample Applic
5858
| Demonstrates how to use Spring Session to replace the `HttpSession` with a relational database store.
5959
| link:guides/boot-jdbc.html[HttpSession with JDBC Guide]
6060

61+
| {gh-samples-url}spring-session-sample-boot-hazelcast[HttpSession with Hazelcast]
62+
| Demonstrates how to use Spring Session to replace the `HttpSession` with Hazelcast.
63+
|
64+
6165
| {gh-samples-url}spring-session-sample-boot-findbyusername[Find by Username]
6266
| Demonstrates how to use Spring Session to find sessions by username.
6367
| link:guides/boot-findbyusername.html[Find by Username Guide]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apply plugin: 'io.spring.convention.spring-sample-boot'
2+
3+
dependencies {
4+
compile project(':spring-session-hazelcast')
5+
compile "org.springframework.boot:spring-boot-starter-web"
6+
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
7+
compile "org.springframework.boot:spring-boot-starter-security"
8+
compile "com.hazelcast:hazelcast-client"
9+
compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect"
10+
compile "org.webjars:bootstrap"
11+
compile "org.webjars:html5shiv"
12+
compile "org.webjars:webjars-locator-core"
13+
14+
testCompile "org.springframework.boot:spring-boot-starter-test"
15+
testCompile "org.junit.jupiter:junit-jupiter-api"
16+
testRuntime "org.junit.jupiter:junit-jupiter-engine"
17+
integrationTestCompile seleniumDependencies
18+
integrationTestCompile "org.testcontainers:testcontainers"
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2014-2020 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 sample;
18+
19+
import org.junit.jupiter.api.AfterEach;
20+
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.ExtendWith;
23+
import org.openqa.selenium.WebDriver;
24+
import org.testcontainers.containers.GenericContainer;
25+
import sample.pages.HomePage;
26+
import sample.pages.LoginPage;
27+
28+
import org.springframework.beans.factory.annotation.Autowired;
29+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
30+
import org.springframework.boot.test.context.SpringBootTest;
31+
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
32+
import org.springframework.boot.test.context.TestConfiguration;
33+
import org.springframework.context.annotation.Bean;
34+
import org.springframework.test.context.junit.jupiter.SpringExtension;
35+
import org.springframework.test.web.servlet.MockMvc;
36+
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
37+
38+
/**
39+
* @author Ellie Bahadori
40+
*/
41+
@ExtendWith(SpringExtension.class)
42+
@AutoConfigureMockMvc
43+
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
44+
class BootTests {
45+
46+
private static final String DOCKER_IMAGE = "hazelcast/hazelcast:latest";
47+
48+
@Autowired
49+
private MockMvc mockMvc;
50+
51+
private WebDriver driver;
52+
53+
@BeforeEach
54+
void setup() {
55+
this.driver = MockMvcHtmlUnitDriverBuilder.mockMvcSetup(this.mockMvc).build();
56+
}
57+
58+
@AfterEach
59+
void tearDown() {
60+
this.driver.quit();
61+
}
62+
63+
@Test
64+
void home() {
65+
LoginPage login = HomePage.go(this.driver);
66+
login.assertAt();
67+
}
68+
69+
@Test
70+
void login() {
71+
LoginPage login = HomePage.go(this.driver);
72+
HomePage home = login.form().login(HomePage.class);
73+
home.assertAt();
74+
home.containCookie("SESSION");
75+
home.doesNotContainCookie("JSESSIONID");
76+
}
77+
78+
@Test
79+
void logout() {
80+
LoginPage login = HomePage.go(this.driver);
81+
HomePage home = login.form().login(HomePage.class);
82+
home.logout();
83+
login.assertAt();
84+
}
85+
86+
@TestConfiguration
87+
static class Config {
88+
89+
@Bean
90+
GenericContainer hazelcastContainer() {
91+
GenericContainer hazelcastContainer = new GenericContainer(DOCKER_IMAGE).withExposedPorts(5701);
92+
hazelcastContainer.start();
93+
return hazelcastContainer;
94+
}
95+
96+
}
97+
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2014-2020 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 sample.pages;
18+
19+
import org.openqa.selenium.WebDriver;
20+
21+
/**
22+
* @author Ellie Bahadori
23+
*/
24+
public class BasePage {
25+
26+
private WebDriver driver;
27+
28+
public BasePage(WebDriver driver) {
29+
this.driver = driver;
30+
}
31+
32+
public WebDriver getDriver() {
33+
return this.driver;
34+
}
35+
36+
public static void get(WebDriver driver, String get) {
37+
String baseUrl = "http://localhost";
38+
driver.get(baseUrl + get);
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2014-2020 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 sample.pages;
18+
19+
import java.util.Set;
20+
21+
import org.openqa.selenium.By;
22+
import org.openqa.selenium.Cookie;
23+
import org.openqa.selenium.WebDriver;
24+
import org.openqa.selenium.WebElement;
25+
import org.openqa.selenium.support.PageFactory;
26+
27+
import static org.assertj.core.api.Assertions.assertThat;
28+
29+
/**
30+
* @author Ellie Bahadori
31+
*/
32+
public class HomePage extends BasePage {
33+
34+
public HomePage(WebDriver driver) {
35+
super(driver);
36+
}
37+
38+
public static LoginPage go(WebDriver driver) {
39+
get(driver, "/");
40+
return PageFactory.initElements(driver, LoginPage.class);
41+
}
42+
43+
public void assertAt() {
44+
assertThat(getDriver().getTitle()).isEqualTo("Spring Session Sample - Secured Content");
45+
}
46+
47+
public void containCookie(String cookieName) {
48+
Set<Cookie> cookies = getDriver().manage().getCookies();
49+
assertThat(cookies).extracting("name").contains(cookieName);
50+
}
51+
52+
public void doesNotContainCookie(String cookieName) {
53+
Set<Cookie> cookies = getDriver().manage().getCookies();
54+
assertThat(cookies).extracting("name").doesNotContain(cookieName);
55+
}
56+
57+
public HomePage logout() {
58+
WebElement logout = getDriver().findElement(By.cssSelector("input[type=\"submit\"]"));
59+
logout.click();
60+
return PageFactory.initElements(getDriver(), HomePage.class);
61+
}
62+
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2014-2020 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 sample.pages;
18+
19+
import org.openqa.selenium.SearchContext;
20+
import org.openqa.selenium.WebDriver;
21+
import org.openqa.selenium.WebElement;
22+
import org.openqa.selenium.support.FindBy;
23+
import org.openqa.selenium.support.PageFactory;
24+
import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
28+
/**
29+
* @author Ellie Bahadori
30+
*/
31+
public class LoginPage extends BasePage {
32+
33+
public LoginPage(WebDriver driver) {
34+
super(driver);
35+
}
36+
37+
public void assertAt() {
38+
assertThat(getDriver().getTitle()).isEqualTo("Please sign in");
39+
}
40+
41+
public Form form() {
42+
return new Form(getDriver());
43+
}
44+
45+
public class Form {
46+
47+
@FindBy(name = "username")
48+
private WebElement username;
49+
50+
@FindBy(name = "password")
51+
private WebElement password;
52+
53+
@FindBy(tagName = "button")
54+
private WebElement button;
55+
56+
public Form(SearchContext context) {
57+
PageFactory.initElements(new DefaultElementLocatorFactory(context), this);
58+
}
59+
60+
public <T> T login(Class<T> page) {
61+
this.username.sendKeys("user");
62+
this.password.sendKeys("password");
63+
this.button.click();
64+
return PageFactory.initElements(getDriver(), page);
65+
}
66+
67+
}
68+
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ryuk.container.timeout=120
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2014-2020 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 sample;
18+
19+
import org.springframework.boot.SpringApplication;
20+
import org.springframework.boot.autoconfigure.SpringBootApplication;
21+
import org.springframework.cache.annotation.EnableCaching;
22+
23+
/**
24+
* @author Ellie Bahadori
25+
*/
26+
@EnableCaching
27+
@SpringBootApplication
28+
public class Application {
29+
30+
public static void main(String[] args) {
31+
SpringApplication.run(Application.class, args);
32+
}
33+
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2014-2020 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 sample.config;
18+
19+
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
20+
import org.springframework.context.annotation.Configuration;
21+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
22+
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
23+
24+
/**
25+
* Spring Security configuration.
26+
*
27+
* @author Ellie Bahadori
28+
*/
29+
@Configuration
30+
public class SecurityConfig extends WebSecurityConfigurerAdapter {
31+
32+
// @formatter:off
33+
// tag::config[]
34+
@Override
35+
protected void configure(HttpSecurity http) throws Exception {
36+
http
37+
.authorizeRequests((authorize) -> authorize
38+
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
39+
.anyRequest().authenticated()
40+
)
41+
.formLogin((formLogin) -> formLogin
42+
.permitAll()
43+
);
44+
}
45+
// end::config[]
46+
// @formatter:on
47+
48+
}

0 commit comments

Comments
 (0)