From 3ec6e49f5b14c4960d247ece215d718c8ecec6e4 Mon Sep 17 00:00:00 2001 From: Greg Turnquist Date: Wed, 23 Aug 2017 11:16:08 -0500 Subject: [PATCH] Add Reactive Spring Boot example --- .travis.yml | 16 +++ CODE_OF_CONDUCT.adoc | 44 ++++++ pom.xml | 1 + .../pom.xml | 64 +++++++++ .../session/mongodb/examples/Config.java | 36 +++++ .../examples/SessionAttributeForm.java | 45 ++++++ .../mongodb/examples/SessionController.java | 46 ++++++ ...SpringSessionMongoReactiveApplication.java | 33 +++++ .../src/main/resources/logback.xml | 14 ++ .../src/main/resources/templates/index.html | 41 ++++++ .../mongodb/examples/AttributeTests.java | 88 ++++++++++++ .../mongodb/examples/pages/HomePage.java | 135 ++++++++++++++++++ .../pom.xml | 2 +- 13 files changed, 564 insertions(+), 1 deletion(-) create mode 100644 .travis.yml create mode 100644 CODE_OF_CONDUCT.adoc create mode 100644 spring-session-data-mongodb-reactive-boot/pom.xml create mode 100644 spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/Config.java create mode 100644 spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionAttributeForm.java create mode 100644 spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionController.java create mode 100644 spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SpringSessionMongoReactiveApplication.java create mode 100644 spring-session-data-mongodb-reactive-boot/src/main/resources/logback.xml create mode 100644 spring-session-data-mongodb-reactive-boot/src/main/resources/templates/index.html create mode 100644 spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/AttributeTests.java create mode 100644 spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/pages/HomePage.java diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cdd41d6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: java +jdk: +- oraclejdk8 +env: + matrix: + - PROFILE=non-existent + - PROFILE=spring5-next +cache: + directories: + - $HOME/.m2 +os: +- linux +branches: + except: + - gh-pages +sudo: false diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc new file mode 100644 index 0000000..f013d6f --- /dev/null +++ b/CODE_OF_CONDUCT.adoc @@ -0,0 +1,44 @@ += Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open +and welcoming community, we pledge to respect all people who contribute through reporting +issues, posting feature requests, updating documentation, submitting pull requests or +patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for +everyone, regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, body size, race, ethnicity, age, +religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic addresses, + without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or reject comments, +commits, code, wiki edits, issues, and other contributions that are not aligned to this +Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors +that they deem inappropriate, threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to fairly and +consistently applying these principles to every aspect of managing this project. Project +maintainers who do not follow or enforce the Code of Conduct may be permanently removed +from the project team. + +This Code of Conduct applies both within project spaces and in public spaces when an +individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by +contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will +be reviewed and investigated and will result in a response that is deemed necessary and +appropriate to the circumstances. Maintainers are obligated to maintain confidentiality +with regard to the reporter of an incident. + +This Code of Conduct is adapted from the +http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at +http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/] diff --git a/pom.xml b/pom.xml index 261deac..58a3440 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,7 @@ spring-session-data-mongodb-traditional-boot + spring-session-data-mongodb-reactive-boot diff --git a/spring-session-data-mongodb-reactive-boot/pom.xml b/spring-session-data-mongodb-reactive-boot/pom.xml new file mode 100644 index 0000000..b6a27e0 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/pom.xml @@ -0,0 +1,64 @@ + + + 4.0.0 + + + org.springframework.session.data.mongodb + spring-session-data-mongodb-examples + 1.0.0.BUILD-SNAPSHOT + + + org.springframework.session.data.mongodb + spring-session-data-mongodb-reactive-boot + jar + + Spring Session MongoDB - Examples - Reactive Spring Boot + + + + + org.springframework.boot + spring-boot-starter-data-mongodb-reactive + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.seleniumhq.selenium + htmlunit-driver + test + + + org.seleniumhq.selenium + selenium-support + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/Config.java b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/Config.java new file mode 100644 index 0000000..26563c3 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/Config.java @@ -0,0 +1,36 @@ +/* + * Copyright 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.mongodb.examples; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository; +import org.springframework.session.web.server.session.SpringSessionWebSessionManager; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; +import org.springframework.web.server.session.WebSessionManager; + +/** + * @author Greg Turnquist + */ +@Configuration +public class Config { + + @Bean(WebHttpHandlerBuilder.WEB_SESSION_MANAGER_BEAN_NAME) + public WebSessionManager webSessionManager(ReactiveMongoOperations operations) { + return new SpringSessionWebSessionManager(new ReactiveMongoOperationsSessionRepository(operations)); + } +} diff --git a/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionAttributeForm.java b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionAttributeForm.java new file mode 100644 index 0000000..0d863f4 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionAttributeForm.java @@ -0,0 +1,45 @@ +/* + * 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.mongodb.examples; + +/** + * @author Rob Winch + * @author Greg Turnquist + * @since 5.0 + */ +public class SessionAttributeForm { + + private String attributeName; + + private String attributeValue; + + public String getAttributeName() { + return this.attributeName; + } + + public void setAttributeName(String attributeName) { + this.attributeName = attributeName; + } + + public String getAttributeValue() { + return this.attributeValue; + } + + public void setAttributeValue(String attributeValue) { + this.attributeValue = attributeValue; + } +} diff --git a/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionController.java b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionController.java new file mode 100644 index 0000000..3bc4be0 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SessionController.java @@ -0,0 +1,46 @@ +/* + * 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.mongodb.examples; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.server.WebSession; + +/** + * @author Rob Winch + * @author Greg Turnquist + */ +// tag::class[] +@Controller +public class SessionController { + + @PostMapping("/session") + public String setAttribute(@ModelAttribute SessionAttributeForm sessionAttributeForm, WebSession session) { + session.getAttributes().put(sessionAttributeForm.getAttributeName(), sessionAttributeForm.getAttributeValue()); + return "redirect:/"; + } + + @GetMapping("/") + public String index(Model model, WebSession webSession) { + model.addAttribute("webSession", webSession); + return "index"; + } +} +// tag::end[] diff --git a/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SpringSessionMongoReactiveApplication.java b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SpringSessionMongoReactiveApplication.java new file mode 100644 index 0000000..37ea483 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/main/java/org/springframework/session/mongodb/examples/SpringSessionMongoReactiveApplication.java @@ -0,0 +1,33 @@ +/* + * Copyright 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.mongodb.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Pure Spring-based application (using Spring Boot for dependency management), hence no autoconfiguration. + * + * @author Rob Winch + * @author Greg Turnquist + */ +@SpringBootApplication +public class SpringSessionMongoReactiveApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringSessionMongoReactiveApplication.class); + } +} diff --git a/spring-session-data-mongodb-reactive-boot/src/main/resources/logback.xml b/spring-session-data-mongodb-reactive-boot/src/main/resources/logback.xml new file mode 100644 index 0000000..2ea1e08 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + diff --git a/spring-session-data-mongodb-reactive-boot/src/main/resources/templates/index.html b/spring-session-data-mongodb-reactive-boot/src/main/resources/templates/index.html new file mode 100644 index 0000000..3d0039b --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/main/resources/templates/index.html @@ -0,0 +1,41 @@ + + + + Session Attributes + + + +
+

Description

+

This application demonstrates how to use a Redis instance to back your session. Notice that there is no + JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.

+ +

Try it

+ +
+ + + + + +
+ +
+ + + + + + + + + + + + +
Attribute NameAttribute Value
+ +
+
+ + \ No newline at end of file diff --git a/spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/AttributeTests.java b/spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/AttributeTests.java new file mode 100644 index 0000000..2fb2625 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/AttributeTests.java @@ -0,0 +1,88 @@ +/* + * 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.mongodb.examples; + + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.htmlunit.HtmlUnitDriver; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.session.mongodb.examples.pages.HomePage; +import org.springframework.session.mongodb.examples.pages.HomePage.Attribute; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Eddú Meléndez + * @author Rob Winch + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class AttributeTests { + + @LocalServerPort + int port; + + private WebDriver driver; + + @Before + public void setup() { + this.driver = new HtmlUnitDriver(); + } + + @After + public void tearDown() { + this.driver.quit(); + } + + @Test + public void home() { + HomePage home = HomePage.go(this.driver, this.port); + home.assertAt(); + } + + @Test + public void noAttributes() { + HomePage home = HomePage.go(this.driver, this.port); + assertThat(home.attributes()).isEmpty(); + } + + @Test + public void createAttribute() { + HomePage home = HomePage.go(this.driver, this.port); + // @formatter:off + home = home.form() + .attributeName("a") + .attributeValue("b") + .submit(HomePage.class); + // @formatter:on + + List attributes = home.attributes(); + assertThat(attributes).hasSize(1); + Attribute row = attributes.get(0); + assertThat(row.getAttributeName()).isEqualTo("a"); + assertThat(row.getAttributeValue()).isEqualTo("b"); + } + +} diff --git a/spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/pages/HomePage.java b/spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/pages/HomePage.java new file mode 100644 index 0000000..1b2bfc9 --- /dev/null +++ b/spring-session-data-mongodb-reactive-boot/src/test/java/org/springframework/session/mongodb/examples/pages/HomePage.java @@ -0,0 +1,135 @@ +/* + * 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.mongodb.examples.pages; + +import static org.assertj.core.api.Assertions.*; + +import java.util.ArrayList; +import java.util.List; + +import org.openqa.selenium.SearchContext; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.PageFactory; +import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory; + +/** + * @author Eddú Meléndez + * @author Rob Winch + */ +public class HomePage { + + private WebDriver driver; + + @FindBy(css = "form") + WebElement form; + + @FindBy(css = "table tbody tr") + List trs; + + List attributes; + + public HomePage(WebDriver driver) { + this.driver = driver; + this.attributes = new ArrayList<>(); + } + + private static void get(WebDriver driver, int port, String get) { + String baseUrl = "http://localhost:" + port; + driver.get(baseUrl + get); + } + + public static HomePage go(WebDriver driver, int port) { + get(driver, port, "/"); + return PageFactory.initElements(driver, HomePage.class); + } + + public void assertAt() { + assertThat(this.driver.getTitle()).isEqualTo("Session Attributes"); + } + + public List attributes() { + List rows = new ArrayList<>(); + for (WebElement tr : this.trs) { + rows.add(new Attribute(tr)); + } + this.attributes.addAll(rows); + return this.attributes; + } + + public Form form() { + return new Form(this.form); + } + + public class Form { + @FindBy(name = "attributeName") + WebElement attributeName; + + @FindBy(name = "attributeValue") + WebElement attributeValue; + + @FindBy(css = "input[type=\"submit\"]") + WebElement submit; + + public Form(SearchContext context) { + PageFactory.initElements(new DefaultElementLocatorFactory(context), this); + } + + public Form attributeName(String text) { + this.attributeName.sendKeys(text); + return this; + } + + public Form attributeValue(String text) { + this.attributeValue.sendKeys(text); + return this; + } + + public T submit(Class page) { + this.submit.click(); + return PageFactory.initElements(HomePage.this.driver, page); + } + } + + public static class Attribute { + @FindBy(xpath = ".//td[1]") + WebElement attributeName; + + @FindBy(xpath = ".//td[2]") + WebElement attributeValue; + + public Attribute(SearchContext context) { + PageFactory.initElements(new DefaultElementLocatorFactory(context), this); + } + + /** + * @return the attributeName + */ + public String getAttributeName() { + return this.attributeName.getText(); + } + + /** + * @return the attributeValue + */ + public String getAttributeValue() { + return this.attributeValue.getText(); + } + } + +} diff --git a/spring-session-data-mongodb-traditional-boot/pom.xml b/spring-session-data-mongodb-traditional-boot/pom.xml index 87bc229..cfd0f6f 100644 --- a/spring-session-data-mongodb-traditional-boot/pom.xml +++ b/spring-session-data-mongodb-traditional-boot/pom.xml @@ -14,7 +14,7 @@ spring-session-data-mongodb-traditional-boot jar - Spring Session MongoDB - Examples - Traditional Boot + Spring Session MongoDB - Examples - Traditional Spring Boot