Break out examples to separate repo

This repository is simplified by putting all examples into spring-session-data-mongodb-examples.
This commit is contained in:
Greg Turnquist
2017-08-02 12:23:33 -05:00
parent a9bcfaabe6
commit c9b034aeef
21 changed files with 20 additions and 610 deletions

31
pom.xml
View File

@@ -6,12 +6,6 @@
<artifactId>spring-session-data-mongodb</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.0.0.RC2</version>
</parent>
<name>Spring Session MongoDB</name>
<url>https://github.com/spring-projects/spring-session-data-mongodb</url>
<description>
@@ -77,9 +71,11 @@
<assertj.version>3.6.2</assertj.version>
<flapdoodle.version>1.50.5</flapdoodle.version>
<hamcrest.version>1.3</hamcrest.version>
<jackson.version>2.9.0.pr3</jackson.version>
<jackson.version>2.9.0</jackson.version>
<junit.version>4.12</junit.version>
<mockito.version>2.7.22</mockito.version>
<mongo.version>3.4.2</mongo.version>
<mongo-reactivestreams.version>1.5.0</mongo-reactivestreams.version>
<reactor.version>Bismuth-M3</reactor.version>
<spring.version>5.0.0.RC3</spring.version>
<spring-data.version>Kay-RC2</spring-data.version>
@@ -310,10 +306,11 @@
<backend>html</backend>
<doctype>book</doctype>
<attributes>
<allow-uri-read>true</allow-uri-read>
<docinfo>true</docinfo>
<github-tag>v${project.version}</github-tag>
<asciidoc-base>${basedir}/src/main/asciidoc</asciidoc-base>
<docs-test-dir>${basedir}/src/main/asciidoc/java</docs-test-dir>
<code-dir>${basedir}</code-dir>
<samples-dir>https://raw.githubusercontent.com/gregturn/spring-session-data-mongodb-examples/master</samples-dir>
<spring-session-version>${spring-session.version}</spring-session-version>
</attributes>
</configuration>
@@ -467,7 +464,8 @@
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>${mongo}</version>
<version>${mongo.version}</version>
<optional>true</optional>
</dependency>
<dependency>
@@ -487,11 +485,13 @@
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@@ -541,24 +541,17 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>${mongo}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-async</artifactId>
<version>${mongo}</version>
<version>${mongo.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<version>${mongo.reactivestreams}</version>
<version>${mongo-reactivestreams.version}</version>
<scope>test</scope>
</dependency>

View File

@@ -1 +0,0 @@
Demonstrates using Spring Session with Spring Boot and Spring Security. You can log in with the username "user" and the password "password".

View File

@@ -1,19 +0,0 @@
apply plugin: 'io.spring.convention.spring-sample-boot'
dependencies {
compile project(':spring-session')
compile "org.springframework.data:spring-data-mongodb"
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-security"
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect"
compile "org.webjars:bootstrap"
compile "org.webjars:html5shiv"
compile "org.webjars:webjars-locator"
compile "de.flapdoodle.embed:de.flapdoodle.embed.mongo"
testCompile "org.springframework.boot:spring-boot-starter-test"
integrationTestCompile seleniumDependencies
}

View File

@@ -1,104 +0,0 @@
/*
* 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.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import sample.pages.HomePage;
import sample.pages.LoginPage;
import org.springframework.beans.factory.annotation.Autowired;
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.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Pool Dolorier
*/
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
public class BootTests {
@Autowired
private MockMvc mockMvc;
private WebDriver driver;
@Before
public void setUp() {
this.driver = MockMvcHtmlUnitDriverBuilder
.mockMvcSetup(this.mockMvc)
.build();
}
@After
public void tearDown() {
this.driver.quit();
}
@Test
public void unauthenticatedUserSentToLogInPage() {
HomePage homePage = HomePage.go(this.driver);
LoginPage loginPage = homePage.unauthenticated();
loginPage.assertAt();
}
@Test
public void logInViewsHomePage() {
LoginPage loginPage = LoginPage.go(this.driver);
loginPage.assertAt();
HomePage homePage = loginPage.login("user", "password");
homePage.assertAt();
WebElement username = homePage.getDriver().findElement(By.id("un"));
assertThat(username.getText()).isEqualTo("user");
Set<Cookie> cookies = homePage.getDriver().manage().getCookies();
assertThat(cookies).extracting("name").contains("SESSION");
assertThat(cookies).extracting("name").doesNotContain("JSESSIONID");
}
@Test
public void logoutSuccess() {
LoginPage loginPage = LoginPage.go(this.driver);
HomePage homePage = loginPage.login("user", "password");
LoginPage successLogoutPage = homePage.logout();
successLogoutPage.assertAt();
}
@Test
public void loggedOutUserSentToLoginPage() {
LoginPage loginPage = LoginPage.go(this.driver);
HomePage homePage = loginPage.login("user", "password");
homePage.logout();
HomePage backHomePage = HomePage.go(this.driver);
LoginPage backLoginPage = backHomePage.unauthenticated();
backLoginPage.assertAt();
}
}

View File

@@ -1,40 +0,0 @@
/*
* 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.pages;
import org.openqa.selenium.WebDriver;
/**
* @author Pool Dolorier
*/
public abstract class BasePage {
private WebDriver driver;
public BasePage(WebDriver driver) {
this.driver = driver;
}
public WebDriver getDriver() {
return this.driver;
}
public static void get(WebDriver driver, String get) {
String baseUrl = "http://localhost";
driver.get(baseUrl + get);
}
}

View File

@@ -1,55 +0,0 @@
/*
* 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.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Pool Dolorier
*/
public class HomePage extends BasePage {
@FindBy(css = "input[type='submit']")
private WebElement submit;
public HomePage(WebDriver driver) {
super(driver);
}
public static HomePage go(WebDriver driver) {
get(driver, "/");
return PageFactory.initElements(driver, HomePage.class);
}
public LoginPage unauthenticated() {
return LoginPage.go(getDriver());
}
public LoginPage logout() {
this.submit.click();
return LoginPage.go(getDriver());
}
public void assertAt() {
assertThat(getDriver().getTitle()).isEqualTo("Spring Session Sample - Secured Content");
}
}

View File

@@ -1,59 +0,0 @@
/*
* 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.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Pool Dolorier
*/
public class LoginPage extends BasePage {
@FindBy(name = "username")
private WebElement username;
@FindBy(name = "password")
private WebElement password;
@FindBy(css = "input[name='submit']")
private WebElement submit;
public LoginPage(WebDriver driver) {
super(driver);
}
public static LoginPage go(WebDriver driver) {
get(driver, "/login");
return PageFactory.initElements(driver, LoginPage.class);
}
public void assertAt() {
assertThat(getDriver().getTitle()).isEqualTo("Login Page");
}
public HomePage login(String user, String password) {
this.username.sendKeys(user);
this.password.sendKeys(password);
this.submit.click();
return HomePage.go(getDriver());
}
}

View File

@@ -1,30 +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 sample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Rob Winch
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -1,44 +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 sample;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
class EmbeddedMongoPortLogger implements ApplicationRunner, EnvironmentAware {
private static final Logger logger = LoggerFactory.getLogger(EmbeddedMongoPortLogger.class);
private Environment environment;
public void run(ApplicationArguments args) throws Exception {
String port = this.environment.getProperty("local.mongo.port");
logger.info("Embedded Mongo started on port " + port +
", use 'mongo --port " + port + "' command to connect");
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}

View File

@@ -1,31 +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 sample.config;
import org.springframework.context.annotation.Bean;
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
// tag::class[]
@EnableMongoHttpSession // <1>
public class HttpSessionConfig {
@Bean
public JdkMongoSessionConverter jdkMongoSessionConverter() {
return new JdkMongoSessionConverter(); // <2>
}
}
// end::class[]

View File

@@ -1,33 +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 sample.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @author Rob Winch
*/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}

View File

@@ -1,33 +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 sample.mvc;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Controller for sending the user to the login view.
*
* @author Rob Winch
*
*/
@Controller
public class IndexController {
@RequestMapping("/")
public String index() {
return "index";
}
}

View File

@@ -1,3 +0,0 @@
spring.thymeleaf.cache=false
spring.template.cache=false
spring.data.mongodb.port=0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,11 +0,0 @@
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="layout">
<head>
<title>Secured Content</title>
</head>
<body>
<div layout:fragment="content">
<h1>Secured Page</h1>
<p>This page is secured using Spring Boot, Spring Session, and Spring Security.</p>
</div>
</body>
</html>

View File

@@ -1,122 +0,0 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-3.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Spring Session Sample</title>
<link rel="icon" type="image/x-icon" th:href="@{/resources/img/favicon.ico}" href="../static/img/favicon.ico"/>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet"></link>
<style type="text/css">
/* Sticky footer styles
-------------------------------------------------- */
html,
body {
height: 100%;
/* The html and body elements cannot have any padding or margin. */
}
/* Wrapper for page content to push down footer */
#wrap {
min-height: 100%;
height: auto !important;
height: 100%;
/* Negative indent footer by it's height */
margin: 0 auto -60px;
}
/* Set the fixed height of the footer here */
#push,
#footer {
height: 60px;
}
#footer {
background-color: #f5f5f5;
}
/* Lastly, apply responsive CSS fixes as necessary */
@media (max-width: 767px) {
#footer {
margin-left: -20px;
margin-right: -20px;
padding-left: 20px;
padding-right: 20px;
}
}
/* Custom page CSS
-------------------------------------------------- */
/* Not required for template or sticky footer method. */
.container {
width: auto;
max-width: 680px;
}
.container .credit {
margin: 20px 0;
text-align: center;
}
a {
color: green;
}
.navbar-form {
margin-left: 1em;
}
</style>
<link th:href="@{/webjars/bootstrap/css/bootstrap-responsive.min.css}" href="/webjars/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet"></link>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script th:src="@{/webjars/html5shiv/html5shiv.min.js}" src="/webjars/html5shiv/html5shiv.min.js"></script>
<![endif]-->
</head>
<body>
<div id="wrap">
<div class="navbar navbar-inverse navbar-static-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" th:href="@{/}"><img th:src="@{/resources/img/logo.png}" alt="Spring Security Sample"/></a>
<div class="nav-collapse collapse"
th:with="currentUser=${#httpServletRequest.userPrincipal?.principal}">
<div th:if="${currentUser != null}">
<form class="navbar-form pull-right" th:action="@{/logout}" method="post">
<input type="submit" value="Log out" />
</form>
<p id="un" class="navbar-text pull-right" th:text="${currentUser.username}">
sample_user
</p>
</div>
<ul class="nav">
</ul>
</div>
</div>
</div>
</div>
<!-- Begin page content -->
<div class="container">
<div class="alert alert-success"
th:if="${globalMessage}"
th:text="${globalMessage}">
Some Success message
</div>
<div layout:fragment="content">
Fake content
</div>
</div>
<div id="push"><!-- --></div>
</div>
<div id="footer">
<div class="container">
<p class="muted credit">Visit the <a href="http://spring.io/spring-security">Spring Security</a> site for more <a href="https://github.com/spring-projects/spring-security/blob/master/samples/">samples</a>.</p>
</div>
</div>
</body>
</html>

View File

@@ -1,5 +1,5 @@
= Spring Session - Mongo Repositories
Jakub Kubrynski
Jakub Kubrynski, Greg Turnquist
:toc:
This guide describes how to use Spring Session backed by Mongo.
@@ -74,7 +74,7 @@ All you have to do is to add the following Spring Configuration:
[source,java]
----
include::{samples-dir}boot/mongo/src/main/java/sample/config/HttpSessionConfig.java[tags=class]
include::{samples-dir}/spring-session-data-mongodb-traditional-boot/src/main/java/sample/config/HttpSessionConfig.java[tag=class]
----
<1> The `@EnableMongoHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.

View File

@@ -56,7 +56,7 @@ If you would like to provide custom Jackson modules you can do it by explicitly
[source,java,indent=0]
----
include::{docs-test-dir}/docs/http/MongoJacksonSessionConfiguration.java[tags=config]
include::{code-dir}/src/test/java/org/springframework/session/data/mongo/integration/MongoRepositoryJacksonITest.java[tag=sample]
----
==== JdkMongoSessionConverter
@@ -68,7 +68,7 @@ You can explicitly register `JdkMongoSessionConverter` by defining it as a Bean.
[source,java,indent=0]
----
include::{docs-test-dir}/docs/http/MongoJdkSessionConfiguration.java[tags=config]
include::{code-dir}/src/test/java/org/springframework/session/data/mongo/integration/MongoRepositoryJdkSerializationITest.java[tag=sample]
----
There is also a constructor taking `Serializer` and `Deserializer` objects, allowing you to pass custom implementations, which is especially important when you want to use non-default classloader.

View File

@@ -61,6 +61,7 @@ public class MongoRepositoryJacksonITest extends AbstractMongoRepositoryITest {
assertThat(findByCartId.keySet()).containsOnly(toSave.getId());
}
// tag::sample[]
@Configuration
@EnableMongoHttpSession
static class Config extends BaseConfig {
@@ -69,6 +70,6 @@ public class MongoRepositoryJacksonITest extends AbstractMongoRepositoryITest {
public AbstractMongoSessionConverter mongoSessionConverter() {
return new JacksonMongoSessionConverter(Collections.<Module>singletonList(new GeoModule()));
}
}
// end::sample[]
}

View File

@@ -78,6 +78,7 @@ public class MongoRepositoryJdkSerializationITest extends AbstractMongoRepositor
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
}
// tag::sample[]
@Configuration
@EnableMongoHttpSession
static class Config extends BaseConfig {
@@ -86,6 +87,6 @@ public class MongoRepositoryJdkSerializationITest extends AbstractMongoRepositor
public AbstractMongoSessionConverter mongoSessionConverter() {
return new JdkMongoSessionConverter();
}
}
// end::sample[]
}