From 416c103cdae797b9314cccb9ea1f43b36b4d6b17 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Fri, 24 May 2019 15:01:37 -0300 Subject: [PATCH 01/74] Created new empty module spring-mvc-basics --- .gitignore | 4 + spring-mvc-basics/README.md | 8 + spring-mvc-basics/pom.xml | 299 ++++++++++++++++++ .../com/baeldung/config/AppInitializer.java | 27 ++ .../src/main/resources/annotations.properties | 0 .../SpringContextIntegrationTest.java | 21 ++ 6 files changed, 359 insertions(+) create mode 100644 spring-mvc-basics/README.md create mode 100644 spring-mvc-basics/pom.xml create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/config/AppInitializer.java create mode 100644 spring-mvc-basics/src/main/resources/annotations.properties create mode 100644 spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java diff --git a/.gitignore b/.gitignore index 50cb889e5b..e84b19c168 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ */bin/* +bin/ *.class @@ -21,6 +22,9 @@ *.iws out/ +# VSCode +.vscode/ + # Mac .DS_Store diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md new file mode 100644 index 0000000000..46681afb48 --- /dev/null +++ b/spring-mvc-basics/README.md @@ -0,0 +1,8 @@ +========= + +## Spring MVC Basics with Java Configuration Example Project + +### The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles: diff --git a/spring-mvc-basics/pom.xml b/spring-mvc-basics/pom.xml new file mode 100644 index 0000000000..777537b0b9 --- /dev/null +++ b/spring-mvc-basics/pom.xml @@ -0,0 +1,299 @@ + + 4.0.0 + com.baeldung + spring-mvc-basics + 0.1-SNAPSHOT + spring-mvc-basics + war + + + parent-spring-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-spring-5 + + + + + org.springframework + spring-webmvc + ${spring.version} + + + javax.servlet + javax.servlet-api + 4.0.1 + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.3 + + + javax.servlet + jstl + ${jstl.version} + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + + org.aspectj + aspectjrt + 1.9.1 + + + org.aspectj + aspectjweaver + 1.9.1 + + + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + commons-io + commons-io + + + + + net.sourceforge.htmlunit + htmlunit + 2.32 + + + commons-logging + commons-logging + + + commons-io + commons-io + + + + + commons-io + commons-io + ${commons-io.version} + + + + + org.thymeleaf + thymeleaf-spring4 + ${thymeleaf.version} + + + org.thymeleaf + thymeleaf + ${thymeleaf.version} + + + + com.jayway.jsonpath + json-path + test + 2.4.0 + + + org.springframework + spring-test + ${spring.version} + test + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.hibernate.validator + hibernate-validator + ${hibernate-validator.version} + + + + + + com.google.code.gson + gson + 2.8.5 + + + org.springframework + spring-websocket + ${spring.version} + + + + org.springframework + spring-messaging + ${spring.version} + + + + + spring-mvc-basics + + + src/main/resources + true + + + + + + + maven-resources-plugin + ${maven-resources-plugin.version} + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + false + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + jetty8x + embedded + + + + + + + 8082 + + + + + + + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*IntegrationTest.java + **/*IntTest.java + + + **/*LiveTest.java + + + + + + + json + + + + + org.codehaus.cargo + cargo-maven2-plugin + + false + + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + + + + + + + + + 3.0.9.RELEASE + + + 6.0.10.Final + 5.1.40 + + + 6.0.10.Final + + + 19.0 + 3.5 + 1.3.2 + 2.5 + 2.2.0 + + + 4.4.5 + 4.5.2 + 3.0.7 + 2.23 + + + 3.2.2 + 2.7 + 1.6.1 + 3.1.0 + + + 1.9.1 + + + 3.16-beta1 + + 3.0.1-b06 + + + + + diff --git a/spring-mvc-basics/src/main/java/com/baeldung/config/AppInitializer.java b/spring-mvc-basics/src/main/java/com/baeldung/config/AppInitializer.java new file mode 100644 index 0000000000..a76d955e4f --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/config/AppInitializer.java @@ -0,0 +1,27 @@ +package com.baeldung.config; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; + +import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; + +public class AppInitializer implements WebApplicationInitializer { + + @Override + public void onStartup(ServletContext container) throws ServletException { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + + context.scan("com.baeldung"); + + container.addListener(new ContextLoaderListener(context)); + + ServletRegistration.Dynamic dispatcher = container.addServlet("mvc", new DispatcherServlet(context)); + dispatcher.setLoadOnStartup(1); + dispatcher.addMapping("/"); + } + +} diff --git a/spring-mvc-basics/src/main/resources/annotations.properties b/spring-mvc-basics/src/main/resources/annotations.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..d8cf4cfc0d --- /dev/null +++ b/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,21 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.config.AppInitializer; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { AppInitializer.class }, loader = AnnotationConfigContextLoader.class) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + + } +} From 20c2c2dd7634c37d15ac405287bd8e9b52756f00 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Sat, 25 May 2019 12:03:17 -0300 Subject: [PATCH 02/74] * moved 'Spring MVC Tutorial' code from spring-mvc-java to new module spring-mvc-basics * cleaned spring-mvc-basics pom --- spring-mvc-basics/.gitignore | 13 + spring-mvc-basics/README.md | 1 + spring-mvc-basics/pom.xml | 253 +----------------- .../baeldung/spring/web/config/WebConfig.java | 33 +++ .../web/controller/SampleController.java | 13 + .../src/main/resources/annotations.properties | 0 .../src/main/resources/mvc-configuration.xml | 20 ++ .../src/main/webapp/WEB-INF/view/index.jsp | 7 + .../src/main/webapp/WEB-INF/view/sample.jsp | 7 + spring-mvc-java/README.md | 1 - spring-mvc-java/pom.xml | 1 - 11 files changed, 103 insertions(+), 246 deletions(-) create mode 100644 spring-mvc-basics/.gitignore create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java delete mode 100644 spring-mvc-basics/src/main/resources/annotations.properties create mode 100644 spring-mvc-basics/src/main/resources/mvc-configuration.xml create mode 100644 spring-mvc-basics/src/main/webapp/WEB-INF/view/index.jsp create mode 100644 spring-mvc-basics/src/main/webapp/WEB-INF/view/sample.jsp diff --git a/spring-mvc-basics/.gitignore b/spring-mvc-basics/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-mvc-basics/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index 46681afb48..63d046de2d 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -6,3 +6,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: +- [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) diff --git a/spring-mvc-basics/pom.xml b/spring-mvc-basics/pom.xml index 777537b0b9..8217421948 100644 --- a/spring-mvc-basics/pom.xml +++ b/spring-mvc-basics/pom.xml @@ -1,4 +1,5 @@ - 4.0.0 com.baeldung @@ -15,136 +16,33 @@ - - org.springframework + + org.springframework spring-webmvc ${spring.version} javax.servlet javax.servlet-api - 4.0.1 + ${javax.servlet-api.version} javax.servlet.jsp javax.servlet.jsp-api - 2.3.3 + ${javax.jsp-api.version} javax.servlet jstl ${jstl.version} - - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - org.aspectj - aspectjrt - 1.9.1 - - - org.aspectj - aspectjweaver - 1.9.1 - - - - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - - - commons-io - commons-io - - - - - net.sourceforge.htmlunit - htmlunit - 2.32 - - - commons-logging - commons-logging - - - commons-io - commons-io - - - - - commons-io - commons-io - ${commons-io.version} - - - - - org.thymeleaf - thymeleaf-spring4 - ${thymeleaf.version} - - - org.thymeleaf - thymeleaf - ${thymeleaf.version} - - - - com.jayway.jsonpath - json-path - test - 2.4.0 - org.springframework spring-test - ${spring.version} + ${spring.version} test - - - - org.apache.poi - poi-ooxml - ${poi.version} - - - - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - - - - - - com.google.code.gson - gson - 2.8.5 - - - org.springframework - spring-websocket - ${spring.version} - - - - org.springframework - spring-messaging - ${spring.version} - @@ -155,144 +53,11 @@ true - - - - - maven-resources-plugin - ${maven-resources-plugin.version} - - - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - false - - - - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - jetty8x - embedded - - - - - - - 8082 - - - - - - - - - live - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*IntegrationTest.java - **/*IntTest.java - - - **/*LiveTest.java - - - - - - - json - - - - - org.codehaus.cargo - cargo-maven2-plugin - - false - - - - start-server - pre-integration-test - - start - - - - stop-server - post-integration-test - - stop - - - - - - - - - - - 3.0.9.RELEASE - - - 6.0.10.Final - 5.1.40 - - - 6.0.10.Final - - - 19.0 - 3.5 - 1.3.2 - 2.5 - 2.2.0 - - - 4.4.5 - 4.5.2 - 3.0.7 - 2.23 - - - 3.2.2 - 2.7 - 1.6.1 - 3.1.0 - - - 1.9.1 - - - 3.16-beta1 - - 3.0.1-b06 - + 4.0.1 + 2.3.3 diff --git a/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java new file mode 100644 index 0000000000..6ee20d7a6b --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -0,0 +1,33 @@ +package com.baeldung.spring.web.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.JstlView; + +@EnableWebMvc +@Configuration +@ComponentScan(basePackages = { "com.baeldung.web.controller" }) +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + registry.addViewController("/") + .setViewName("index"); + } + + @Bean + public ViewResolver viewResolver() { + final InternalResourceViewResolver bean = new InternalResourceViewResolver(); + bean.setViewClass(JstlView.class); + bean.setPrefix("/WEB-INF/view/"); + bean.setSuffix(".jsp"); + bean.setOrder(0); + return bean; + } +} \ No newline at end of file diff --git a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java new file mode 100644 index 0000000000..c13986e005 --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java @@ -0,0 +1,13 @@ +package com.baeldung.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class SampleController { + @GetMapping("/sample") + public String showForm() { + return "sample"; + } + +} diff --git a/spring-mvc-basics/src/main/resources/annotations.properties b/spring-mvc-basics/src/main/resources/annotations.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-mvc-basics/src/main/resources/mvc-configuration.xml b/spring-mvc-basics/src/main/resources/mvc-configuration.xml new file mode 100644 index 0000000000..7505614c99 --- /dev/null +++ b/spring-mvc-basics/src/main/resources/mvc-configuration.xml @@ -0,0 +1,20 @@ + + + + + + + + + /WEB-INF/view/ + + + .jsp + + + + \ No newline at end of file diff --git a/spring-mvc-basics/src/main/webapp/WEB-INF/view/index.jsp b/spring-mvc-basics/src/main/webapp/WEB-INF/view/index.jsp new file mode 100644 index 0000000000..4f4eb0068d --- /dev/null +++ b/spring-mvc-basics/src/main/webapp/WEB-INF/view/index.jsp @@ -0,0 +1,7 @@ + + + + +

This is the body of the index view

+ + \ No newline at end of file diff --git a/spring-mvc-basics/src/main/webapp/WEB-INF/view/sample.jsp b/spring-mvc-basics/src/main/webapp/WEB-INF/view/sample.jsp new file mode 100644 index 0000000000..7cc14b5dcd --- /dev/null +++ b/spring-mvc-basics/src/main/webapp/WEB-INF/view/sample.jsp @@ -0,0 +1,7 @@ + + + + +

This is the body of the sample view

+ + \ No newline at end of file diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 3deeb21afc..2c0f594bd2 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -29,6 +29,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [A Quick Example of Spring Websockets’ @SendToUser Annotation](http://www.baeldung.com/spring-websockets-sendtouser) - [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) - [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) -- [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) - [Working with Date Parameters in Spring](https://www.baeldung.com/spring-date-parameters) - [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml) diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml index 853d8db64c..ffa76d405d 100644 --- a/spring-mvc-java/pom.xml +++ b/spring-mvc-java/pom.xml @@ -34,7 +34,6 @@ javax.servlet jstl ${jstl.version} - From 33d0ac573830369ee113b3689d16b1d775448594 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Sun, 26 May 2019 15:30:12 -0300 Subject: [PATCH 03/74] * Moved Controller vs RestController article code from spring-mvc-java to spring-mvc-basics * now using jupiter tests for the tests involved * fixed error in involved test --- spring-mvc-basics/README.md | 1 + spring-mvc-basics/pom.xml | 14 +++++++ .../main/java/com/baeldung/model/Book.java | 42 +++++++++++++++++++ .../web/controller/SimpleBookController.java | 0 .../controller/SimpleBookRestController.java | 0 .../SpringContextIntegrationTest.java | 2 +- .../SimpleBookControllerIntegrationTest.java | 8 ++-- ...mpleBookRestControllerIntegrationTest.java | 12 +++--- spring-mvc-java/README.md | 1 - 9 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/model/Book.java rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/web/controller/SimpleBookController.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/web/controller/SimpleBookRestController.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/web/controller/SimpleBookControllerIntegrationTest.java (90%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/web/controller/SimpleBookRestControllerIntegrationTest.java (85%) diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index 63d046de2d..aa1fffdf42 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -7,3 +7,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) +- [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) diff --git a/spring-mvc-basics/pom.xml b/spring-mvc-basics/pom.xml index 8217421948..cb9f1be9eb 100644 --- a/spring-mvc-basics/pom.xml +++ b/spring-mvc-basics/pom.xml @@ -36,6 +36,13 @@ jstl ${jstl.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + org.springframework @@ -43,6 +50,12 @@ ${spring.version} test + + com.jayway.jsonpath + json-path + test + ${jayway.json-path.version} + @@ -58,6 +71,7 @@ 4.0.1 2.3.3 + 2.4.0 diff --git a/spring-mvc-basics/src/main/java/com/baeldung/model/Book.java b/spring-mvc-basics/src/main/java/com/baeldung/model/Book.java new file mode 100644 index 0000000000..bdfa1d835a --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/model/Book.java @@ -0,0 +1,42 @@ +package com.baeldung.model; + +public class Book { + + private int id; + private String author; + private String title; + + public Book() { + } + + public Book(int id, String author, String title) { + this.id = id; + this.author = author; + this.title = title; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/SimpleBookController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SimpleBookController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/SimpleBookController.java rename to spring-mvc-basics/src/main/java/com/baeldung/web/controller/SimpleBookController.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/SimpleBookRestController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SimpleBookRestController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/SimpleBookRestController.java rename to spring-mvc-basics/src/main/java/com/baeldung/web/controller/SimpleBookRestController.java diff --git a/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java index d8cf4cfc0d..511e56aeab 100644 --- a/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/SimpleBookControllerIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SimpleBookControllerIntegrationTest.java similarity index 90% rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/SimpleBookControllerIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/web/controller/SimpleBookControllerIntegrationTest.java index 23be3a1655..87d70c2d29 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/SimpleBookControllerIntegrationTest.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SimpleBookControllerIntegrationTest.java @@ -5,19 +5,17 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.baeldung.web.controller.SimpleBookController; - public class SimpleBookControllerIntegrationTest { private MockMvc mockMvc; private static final String CONTENT_TYPE = "application/json;charset=UTF-8"; - @Before + @BeforeEach public void setup() { this.mockMvc = MockMvcBuilders.standaloneSetup(new SimpleBookController()).build(); } diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/SimpleBookRestControllerIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SimpleBookRestControllerIntegrationTest.java similarity index 85% rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/SimpleBookRestControllerIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/web/controller/SimpleBookRestControllerIntegrationTest.java index c5bd53f1a7..294943f2e2 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/SimpleBookRestControllerIntegrationTest.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SimpleBookRestControllerIntegrationTest.java @@ -5,27 +5,25 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.baeldung.web.controller.SimpleBookController; - public class SimpleBookRestControllerIntegrationTest { private MockMvc mockMvc; private static final String CONTENT_TYPE = "application/json;charset=UTF-8"; - @Before + @BeforeEach public void setup() { - this.mockMvc = MockMvcBuilders.standaloneSetup(new SimpleBookController()).build(); + this.mockMvc = MockMvcBuilders.standaloneSetup(new SimpleBookRestController()).build(); } @Test public void givenBookId_whenMockMVC_thenVerifyResponse() throws Exception { this.mockMvc - .perform(get("/books/42")) + .perform(get("/books-rest/42")) .andExpect(status().isOk()) .andExpect(content().contentType(CONTENT_TYPE)) .andExpect(jsonPath("$.id").value(42)); diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 2c0f594bd2..e39ddd8af7 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -24,7 +24,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) - [The HttpMediaTypeNotAcceptableException in Spring MVC](http://www.baeldung.com/spring-httpmediatypenotacceptable) - [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) -- [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) - [Spring MVC @PathVariable with a dot (.) gets truncated](http://www.baeldung.com/spring-mvc-pathvariable-dot) - [A Quick Example of Spring Websockets’ @SendToUser Annotation](http://www.baeldung.com/spring-websockets-sendtouser) - [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) From ee4953b7ef831d4205e505225497adb4073f5793 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Sun, 26 May 2019 17:42:54 -0300 Subject: [PATCH 04/74] * Added example and test for "using @ResponseStatus" article in the spring-mvc-basics module --- spring-mvc-basics/README.md | 1 + .../ResponseStatusRestController.java | 48 +++++++++++++++++ ...seStatusRestControllerIntegrationTest.java | 52 +++++++++++++++++++ spring-mvc-java/README.md | 1 - 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/web/controller/ResponseStatusRestController.java create mode 100644 spring-mvc-basics/src/test/java/com/baeldung/web/controller/ResponseStatusRestControllerIntegrationTest.java diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index aa1fffdf42..c8a0ac6508 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -8,3 +8,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) - [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) +- [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) \ No newline at end of file diff --git a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/ResponseStatusRestController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/ResponseStatusRestController.java new file mode 100644 index 0000000000..4cc7589bc8 --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/ResponseStatusRestController.java @@ -0,0 +1,48 @@ +package com.baeldung.web.controller; + +import java.util.concurrent.ThreadLocalRandom; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.model.Book; + +@RestController +public class ResponseStatusRestController { + + @GetMapping("/teapot") + @ResponseStatus(HttpStatus.I_AM_A_TEAPOT) + public void teaPot() { + } + + @GetMapping("empty") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void emptyResponse() { + } + + @GetMapping("empty-no-responsestatus") + public void emptyResponseWithoutResponseStatus() { + } + + @PostMapping("create") + @ResponseStatus(HttpStatus.CREATED) + public Book createEntity() { + // here we would create and persist an entity + int randomInt = ThreadLocalRandom.current() + .nextInt(1, 100); + Book entity = new Book(randomInt, "author" + randomInt, "title" + randomInt); + return entity; + } + + @PostMapping("create-no-responsestatus") + public Book createEntityWithoutResponseStatus() { + // here we would create and persist an entity + int randomInt = ThreadLocalRandom.current() + .nextInt(1, 100); + Book entity = new Book(randomInt, "author" + randomInt, "title" + randomInt); + return entity; + } +} diff --git a/spring-mvc-basics/src/test/java/com/baeldung/web/controller/ResponseStatusRestControllerIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/ResponseStatusRestControllerIntegrationTest.java new file mode 100644 index 0000000000..1f37a3750c --- /dev/null +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/ResponseStatusRestControllerIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.web.controller; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +public class ResponseStatusRestControllerIntegrationTest { + + private MockMvc mockMvc; + + @BeforeEach + public void setup() { + this.mockMvc = MockMvcBuilders.standaloneSetup(new ResponseStatusRestController()) + .build(); + } + + @Test + public void whenTeapotEndpointCalled_thenTeapotResponseObtained() throws Exception { + this.mockMvc.perform(get("/teapot")) + .andExpect(status().isIAmATeapot()); + } + + @Test + public void whenEmptyNoContentEndpointCalled_thenNoContentResponseObtained() throws Exception { + this.mockMvc.perform(get("/empty")) + .andExpect(status().isNoContent()); + } + + @Test + public void whenEmptyWithoutResponseStatusEndpointCalled_then200ResponseObtained() throws Exception { + this.mockMvc.perform(get("/empty-no-responsestatus")) + .andExpect(status().isOk()); + } + + @Test + public void whenCreateWithCreatedEndpointCalled_thenCreatedResponseObtained() throws Exception { + this.mockMvc.perform(post("/create")) + .andExpect(status().isCreated()); + } + + @Test + public void whenCreateWithoutResponseStatusEndpointCalled_thenCreatedResponseObtained() throws Exception { + this.mockMvc.perform(post("/create-no-responsestatus")) + .andExpect(status().isOk()); + } + +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index e39ddd8af7..4d1a7c172c 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -26,7 +26,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) - [Spring MVC @PathVariable with a dot (.) gets truncated](http://www.baeldung.com/spring-mvc-pathvariable-dot) - [A Quick Example of Spring Websockets’ @SendToUser Annotation](http://www.baeldung.com/spring-websockets-sendtouser) -- [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) - [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) - [Working with Date Parameters in Spring](https://www.baeldung.com/spring-date-parameters) - [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml) From ed7630c2d092cc527dd5274bfb954de7910c10c5 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Sun, 26 May 2019 19:08:28 -0300 Subject: [PATCH 05/74] Moved ViewResolver article related code from spring-mvc-java to spring-mvc-basics --- spring-mvc-basics/README.md | 3 +- spring-mvc-basics/pom.xml | 18 ++++++++-- .../baeldung/spring/web/config/WebConfig.java | 19 +++++++++++ .../web/controller/SampleController.java | 13 +++++++- .../src/main/resources/views.properties | 3 ++ .../src/main/resources/views.xml | 18 +++++----- .../src/main/webapp/WEB-INF/view2/sample2.jsp | 7 ++++ .../src/main/webapp/WEB-INF/view3/sample3.jsp | 7 ++++ .../controller/SampleControllerLiveTest.java | 33 +++++++++++++++++++ spring-mvc-java/README.md | 1 - .../baeldung/spring/web/config/WebConfig.java | 19 ----------- .../src/main/resources/views.properties | 3 -- 12 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 spring-mvc-basics/src/main/resources/views.properties rename {spring-mvc-java => spring-mvc-basics}/src/main/resources/views.xml (65%) create mode 100644 spring-mvc-basics/src/main/webapp/WEB-INF/view2/sample2.jsp create mode 100644 spring-mvc-basics/src/main/webapp/WEB-INF/view3/sample3.jsp create mode 100644 spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java delete mode 100644 spring-mvc-java/src/main/resources/views.properties diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index c8a0ac6508..15b19cc1d0 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -8,4 +8,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) - [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) -- [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) \ No newline at end of file +- [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) +- [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) \ No newline at end of file diff --git a/spring-mvc-basics/pom.xml b/spring-mvc-basics/pom.xml index cb9f1be9eb..3bcf5bc4ca 100644 --- a/spring-mvc-basics/pom.xml +++ b/spring-mvc-basics/pom.xml @@ -36,12 +36,12 @@ jstl ${jstl.version} - + com.fasterxml.jackson.core jackson-databind - ${jackson.version} + ${jackson.version} @@ -56,6 +56,18 @@ test ${jayway.json-path.version} + + io.rest-assured + rest-assured + ${rest-assured.version} + test + + + org.hamcrest + hamcrest-all + ${hamcrest.version} + test + @@ -72,6 +84,8 @@ 4.0.1 2.3.3 2.4.0 + 4.0.0 + 1.3 diff --git a/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java index 6ee20d7a6b..9fa9bd58db 100644 --- a/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -3,12 +3,15 @@ package com.baeldung.spring.web.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; +import org.springframework.web.servlet.view.ResourceBundleViewResolver; +import org.springframework.web.servlet.view.XmlViewResolver; @EnableWebMvc @Configuration @@ -27,7 +30,23 @@ public class WebConfig implements WebMvcConfigurer { bean.setViewClass(JstlView.class); bean.setPrefix("/WEB-INF/view/"); bean.setSuffix(".jsp"); + bean.setOrder(2); + return bean; + } + + @Bean + public ViewResolver resourceBundleViewResolver() { + final ResourceBundleViewResolver bean = new ResourceBundleViewResolver(); + bean.setBasename("views"); bean.setOrder(0); return bean; } + + @Bean + public ViewResolver xmlViewResolver() { + final XmlViewResolver bean = new XmlViewResolver(); + bean.setLocation(new ClassPathResource("views.xml")); + bean.setOrder(1); + return bean; + } } \ No newline at end of file diff --git a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java index c13986e005..ce89669fde 100644 --- a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/SampleController.java @@ -5,9 +5,20 @@ import org.springframework.web.bind.annotation.GetMapping; @Controller public class SampleController { - @GetMapping("/sample") + + @GetMapping("/sample") public String showForm() { return "sample"; } + + @GetMapping("/sample2") + public String showForm2() { + return "sample2"; + } + + @GetMapping("/sample3") + public String showForm3() { + return "sample3"; + } } diff --git a/spring-mvc-basics/src/main/resources/views.properties b/spring-mvc-basics/src/main/resources/views.properties new file mode 100644 index 0000000000..06d042b446 --- /dev/null +++ b/spring-mvc-basics/src/main/resources/views.properties @@ -0,0 +1,3 @@ +sample2.(class)=org.springframework.web.servlet.view.JstlView +sample2.url=/WEB-INF/view2/sample2.jsp + diff --git a/spring-mvc-java/src/main/resources/views.xml b/spring-mvc-basics/src/main/resources/views.xml similarity index 65% rename from spring-mvc-java/src/main/resources/views.xml rename to spring-mvc-basics/src/main/resources/views.xml index 83bca5293d..a44d3deae4 100644 --- a/spring-mvc-java/src/main/resources/views.xml +++ b/spring-mvc-basics/src/main/resources/views.xml @@ -1,10 +1,10 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/spring-mvc-basics/src/main/webapp/WEB-INF/view2/sample2.jsp b/spring-mvc-basics/src/main/webapp/WEB-INF/view2/sample2.jsp new file mode 100644 index 0000000000..c826700a75 --- /dev/null +++ b/spring-mvc-basics/src/main/webapp/WEB-INF/view2/sample2.jsp @@ -0,0 +1,7 @@ + + + + +

This is the body of the sample2 view

+ + \ No newline at end of file diff --git a/spring-mvc-basics/src/main/webapp/WEB-INF/view3/sample3.jsp b/spring-mvc-basics/src/main/webapp/WEB-INF/view3/sample3.jsp new file mode 100644 index 0000000000..b58a0973da --- /dev/null +++ b/spring-mvc-basics/src/main/webapp/WEB-INF/view3/sample3.jsp @@ -0,0 +1,7 @@ + + + + +

This is the body of the sample3 view

+ + \ No newline at end of file diff --git a/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java new file mode 100644 index 0000000000..bd24bb6ff9 --- /dev/null +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java @@ -0,0 +1,33 @@ +package com.baeldung.web.controller; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.RestAssured; + +public class SampleControllerLiveTest { + + private static final String SERVICE_BASE_URL = "/spring-mvc-basics"; + + @Test + public void whenSampleEndpointCalled_thenOkResponseObtained() throws Exception { + RestAssured.get(SERVICE_BASE_URL + "/sample") + .then() + .statusCode(HttpStatus.OK.value()); + } + + @Test + public void whenSample2EndpointCalled_thenOkResponseObtained() throws Exception { + RestAssured.get(SERVICE_BASE_URL + "/sample2") + .then() + .statusCode(HttpStatus.OK.value()); + } + + @Test + public void whenSample3EndpointCalled_thenOkResponseObtained() throws Exception { + RestAssured.get(SERVICE_BASE_URL + "/sample3") + .then() + .statusCode(HttpStatus.OK.value()); + } + +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 4d1a7c172c..c670b153cf 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -9,7 +9,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Bean Annotations](http://www.baeldung.com/spring-bean-annotations) - [Introduction to Pointcut Expressions in Spring](http://www.baeldung.com/spring-aop-pointcut-tutorial) - [Introduction to Advice Types in Spring](http://www.baeldung.com/spring-aop-advice-tutorial) -- [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) - [Integration Testing in Spring](http://www.baeldung.com/integration-testing-in-spring) - [A Quick Guide to Spring MVC Matrix Variables](http://www.baeldung.com/spring-mvc-matrix-variables) - [Intro to WebSockets with Spring](http://www.baeldung.com/websockets-spring) diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java index 191d721dfb..96b50f2c37 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java +++ b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -12,7 +12,6 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Description; import org.springframework.context.support.ResourceBundleMessageSource; -import org.springframework.core.io.ClassPathResource; import org.springframework.http.MediaType; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; @@ -26,8 +25,6 @@ import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; -import org.springframework.web.servlet.view.ResourceBundleViewResolver; -import org.springframework.web.servlet.view.XmlViewResolver; import org.springframework.web.util.UrlPathHelper; import org.thymeleaf.spring4.SpringTemplateEngine; import org.thymeleaf.spring4.view.ThymeleafViewResolver; @@ -110,22 +107,6 @@ public class WebConfig implements WebMvcConfigurer { return multipartResolver; } - - @Bean - public ViewResolver xmlViewResolver() { - final XmlViewResolver bean = new XmlViewResolver(); - bean.setLocation(new ClassPathResource("views.xml")); - bean.setOrder(1); - return bean; - } - - @Bean - public ViewResolver resourceBundleViewResolver() { - final ResourceBundleViewResolver bean = new ResourceBundleViewResolver(); - bean.setBasename("views"); - bean.setOrder(0); - return bean; - } @Override public void extendMessageConverters(final List> converters) { diff --git a/spring-mvc-java/src/main/resources/views.properties b/spring-mvc-java/src/main/resources/views.properties deleted file mode 100644 index 95687cb62a..0000000000 --- a/spring-mvc-java/src/main/resources/views.properties +++ /dev/null @@ -1,3 +0,0 @@ -sample.(class)=org.springframework.web.servlet.view.JstlView -sample.url=/WEB-INF/view/sample.jsp - From 802000d5453fb9000736959849fcbf043eb39629 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Fri, 14 Jun 2019 12:40:42 -0300 Subject: [PATCH 06/74] Migrated spring-mvc-basics to a Spring Boot project --- spring-mvc-basics/pom.xml | 81 +++++-------------- .../main/java/com/baeldung/Application.java | 11 +++ .../baeldung/spring/web/config/WebConfig.java | 10 +-- .../src/main/resources/application.properties | 1 + .../SpringContextIntegrationTest.java | 12 +-- .../controller/SampleControllerLiveTest.java | 2 +- 6 files changed, 41 insertions(+), 76 deletions(-) create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/Application.java create mode 100644 spring-mvc-basics/src/main/resources/application.properties diff --git a/spring-mvc-basics/pom.xml b/spring-mvc-basics/pom.xml index 3bcf5bc4ca..d04bdda8f6 100644 --- a/spring-mvc-basics/pom.xml +++ b/spring-mvc-basics/pom.xml @@ -1,3 +1,4 @@ + @@ -6,87 +7,49 @@ spring-mvc-basics 0.1-SNAPSHOT spring-mvc-basics - war + jar - parent-spring-5 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-spring-5 + ../parent-boot-2 - org.springframework - spring-webmvc - ${spring.version} + org.springframework.boot + spring-boot-starter-web + - javax.servlet - javax.servlet-api - ${javax.servlet-api.version} - - - javax.servlet.jsp - javax.servlet.jsp-api - ${javax.jsp-api.version} + org.apache.tomcat.embed + tomcat-embed-jasper + provided javax.servlet jstl ${jstl.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - - org.springframework - spring-test - ${spring.version} - test - - - com.jayway.jsonpath - json-path - test - ${jayway.json-path.version} - - - io.rest-assured - rest-assured - ${rest-assured.version} - test - - - org.hamcrest - hamcrest-all - ${hamcrest.version} + org.springframework.boot + spring-boot-starter-test test - spring-mvc-basics - - - src/main/resources - true - - + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.Application + JAR + + + - - - 4.0.1 - 2.3.3 - 2.4.0 - 4.0.0 - 1.3 - - diff --git a/spring-mvc-basics/src/main/java/com/baeldung/Application.java b/spring-mvc-basics/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..d58049fb35 --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/Application.java @@ -0,0 +1,11 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java index 9fa9bd58db..a56dfe550f 100644 --- a/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -1,11 +1,9 @@ package com.baeldung.spring.web.config; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; @@ -13,9 +11,9 @@ import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.ResourceBundleViewResolver; import org.springframework.web.servlet.view.XmlViewResolver; -@EnableWebMvc +//@EnableWebMvc +//@ComponentScan(basePackages = { "com.baeldung.web.controller" }) @Configuration -@ComponentScan(basePackages = { "com.baeldung.web.controller" }) public class WebConfig implements WebMvcConfigurer { @Override @@ -33,7 +31,7 @@ public class WebConfig implements WebMvcConfigurer { bean.setOrder(2); return bean; } - + @Bean public ViewResolver resourceBundleViewResolver() { final ResourceBundleViewResolver bean = new ResourceBundleViewResolver(); @@ -41,7 +39,7 @@ public class WebConfig implements WebMvcConfigurer { bean.setOrder(0); return bean; } - + @Bean public ViewResolver xmlViewResolver() { final XmlViewResolver bean = new XmlViewResolver(); diff --git a/spring-mvc-basics/src/main/resources/application.properties b/spring-mvc-basics/src/main/resources/application.properties new file mode 100644 index 0000000000..4de974142e --- /dev/null +++ b/spring-mvc-basics/src/main/resources/application.properties @@ -0,0 +1 @@ +server.servlet.context-path=/spring-mvc-basics \ No newline at end of file diff --git a/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java index 511e56aeab..2feb9efce1 100644 --- a/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/SpringContextIntegrationTest.java @@ -1,17 +1,9 @@ package com.baeldung; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.AnnotationConfigContextLoader; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; -import com.baeldung.config.AppInitializer; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { AppInitializer.class }, loader = AnnotationConfigContextLoader.class) -@WebAppConfiguration +@SpringBootTest public class SpringContextIntegrationTest { @Test diff --git a/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java index bd24bb6ff9..0b958996c9 100644 --- a/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/SampleControllerLiveTest.java @@ -6,7 +6,7 @@ import org.springframework.http.HttpStatus; import io.restassured.RestAssured; public class SampleControllerLiveTest { - + private static final String SERVICE_BASE_URL = "/spring-mvc-basics"; @Test From 1e9364a7dc6663336c2616b3f0f3c12e3ab2ed70 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Fri, 14 Jun 2019 14:36:15 -0300 Subject: [PATCH 07/74] Moved code of article spring-handler-mappings from spring-mvc-java to spring-mvc-basics Renamed beans to avoid collisions --- spring-mvc-basics/README.md | 3 ++- .../handlermapping/BeanNameHandlerMappingController.java | 0 .../handlermapping/SimpleUrlMappingController.java | 0 .../web/controller/handlermapping/WelcomeController.java | 0 .../baeldung/config/BeanNameUrlHandlerMappingConfig.java | 7 +++---- .../com/baeldung/config/HandlerMappingDefaultConfig.java | 2 +- .../baeldung/config/HandlerMappingPrioritiesConfig.java | 6 +++--- .../com/baeldung/config/SimpleUrlHandlerMappingConfig.java | 6 +++--- .../BeanNameMappingConfigIntegrationTest.java | 0 .../HandlerMappingDefaultConfigIntegrationTest.java | 0 .../HandlerMappingPriorityConfigIntegrationTest.java | 0 .../SimpleUrlMappingConfigIntegrationTest.java | 0 .../src/test/resources/BeanNameUrlHandlerMappingConfig.xml | 0 .../resources/ControllerClassNameHandlerMappingConfig.xml | 0 .../test/resources/HandlerMappingConfiguringPriorities.xml | 0 .../src/test/resources/SimpleUrlHandlerMappingConfig.xml | 0 spring-mvc-java/README.md | 1 - 17 files changed, 12 insertions(+), 13 deletions(-) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/web/controller/handlermapping/BeanNameHandlerMappingController.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/web/controller/handlermapping/SimpleUrlMappingController.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/web/controller/handlermapping/WelcomeController.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/config/BeanNameUrlHandlerMappingConfig.java (76%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/config/HandlerMappingDefaultConfig.java (90%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/config/HandlerMappingPrioritiesConfig.java (89%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/config/SimpleUrlHandlerMappingConfig.java (85%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/handlermappings/BeanNameMappingConfigIntegrationTest.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/handlermappings/HandlerMappingDefaultConfigIntegrationTest.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/handlermappings/HandlerMappingPriorityConfigIntegrationTest.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/handlermappings/SimpleUrlMappingConfigIntegrationTest.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/resources/BeanNameUrlHandlerMappingConfig.xml (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/resources/ControllerClassNameHandlerMappingConfig.xml (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/resources/HandlerMappingConfiguringPriorities.xml (100%) rename {spring-mvc-java => spring-mvc-basics}/src/test/resources/SimpleUrlHandlerMappingConfig.xml (100%) diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index 15b19cc1d0..997e6a88df 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -9,4 +9,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) - [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) - [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) -- [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) \ No newline at end of file +- [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) +- [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/handlermapping/BeanNameHandlerMappingController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/handlermapping/BeanNameHandlerMappingController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/handlermapping/BeanNameHandlerMappingController.java rename to spring-mvc-basics/src/main/java/com/baeldung/web/controller/handlermapping/BeanNameHandlerMappingController.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/handlermapping/SimpleUrlMappingController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/handlermapping/SimpleUrlMappingController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/handlermapping/SimpleUrlMappingController.java rename to spring-mvc-basics/src/main/java/com/baeldung/web/controller/handlermapping/SimpleUrlMappingController.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/handlermapping/WelcomeController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/handlermapping/WelcomeController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/handlermapping/WelcomeController.java rename to spring-mvc-basics/src/main/java/com/baeldung/web/controller/handlermapping/WelcomeController.java diff --git a/spring-mvc-java/src/test/java/com/baeldung/config/BeanNameUrlHandlerMappingConfig.java b/spring-mvc-basics/src/test/java/com/baeldung/config/BeanNameUrlHandlerMappingConfig.java similarity index 76% rename from spring-mvc-java/src/test/java/com/baeldung/config/BeanNameUrlHandlerMappingConfig.java rename to spring-mvc-basics/src/test/java/com/baeldung/config/BeanNameUrlHandlerMappingConfig.java index e3dcb15de8..577825d8c5 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/config/BeanNameUrlHandlerMappingConfig.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/config/BeanNameUrlHandlerMappingConfig.java @@ -1,11 +1,10 @@ package com.baeldung.config; -import com.baeldung.web.controller.handlermapping.WelcomeController; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; -import org.springframework.web.servlet.view.InternalResourceViewResolver; + +import com.baeldung.web.controller.handlermapping.WelcomeController; @Configuration public class BeanNameUrlHandlerMappingConfig { @@ -16,7 +15,7 @@ public class BeanNameUrlHandlerMappingConfig { } @Bean("/beanNameUrl") - public WelcomeController welcome() { + public WelcomeController welcomeBeanNameMappingConfig() { return new WelcomeController(); } diff --git a/spring-mvc-java/src/test/java/com/baeldung/config/HandlerMappingDefaultConfig.java b/spring-mvc-basics/src/test/java/com/baeldung/config/HandlerMappingDefaultConfig.java similarity index 90% rename from spring-mvc-java/src/test/java/com/baeldung/config/HandlerMappingDefaultConfig.java rename to spring-mvc-basics/src/test/java/com/baeldung/config/HandlerMappingDefaultConfig.java index d3a329a387..4072278fee 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/config/HandlerMappingDefaultConfig.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/config/HandlerMappingDefaultConfig.java @@ -16,7 +16,7 @@ public class HandlerMappingDefaultConfig { } @Bean - public WelcomeController welcome() { + public WelcomeController welcomeDefaultMappingConfig() { return new WelcomeController(); } diff --git a/spring-mvc-java/src/test/java/com/baeldung/config/HandlerMappingPrioritiesConfig.java b/spring-mvc-basics/src/test/java/com/baeldung/config/HandlerMappingPrioritiesConfig.java similarity index 89% rename from spring-mvc-java/src/test/java/com/baeldung/config/HandlerMappingPrioritiesConfig.java rename to spring-mvc-basics/src/test/java/com/baeldung/config/HandlerMappingPrioritiesConfig.java index 2d80dbfeaf..c5fec171a7 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/config/HandlerMappingPrioritiesConfig.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/config/HandlerMappingPrioritiesConfig.java @@ -16,14 +16,14 @@ import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; public class HandlerMappingPrioritiesConfig { @Bean - BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() { + BeanNameUrlHandlerMapping beanNameUrlHandlerMappingOrder1() { BeanNameUrlHandlerMapping beanNameUrlHandlerMapping = new BeanNameUrlHandlerMapping(); beanNameUrlHandlerMapping.setOrder(1); return beanNameUrlHandlerMapping; } @Bean - public SimpleUrlHandlerMapping simpleUrlHandlerMapping() { + public SimpleUrlHandlerMapping simpleUrlHandlerMappingOrder0() { SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping(); simpleUrlHandlerMapping.setOrder(0); Map urlMap = new HashMap<>(); @@ -37,7 +37,7 @@ public class HandlerMappingPrioritiesConfig { return new SimpleUrlMappingController(); } - @Bean("/welcome") + @Bean("/welcome-priorities") public BeanNameHandlerMappingController beanNameHandlerMapping() { return new BeanNameHandlerMappingController(); } diff --git a/spring-mvc-java/src/test/java/com/baeldung/config/SimpleUrlHandlerMappingConfig.java b/spring-mvc-basics/src/test/java/com/baeldung/config/SimpleUrlHandlerMappingConfig.java similarity index 85% rename from spring-mvc-java/src/test/java/com/baeldung/config/SimpleUrlHandlerMappingConfig.java rename to spring-mvc-basics/src/test/java/com/baeldung/config/SimpleUrlHandlerMappingConfig.java index c7921c2706..7a366ecbd7 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/config/SimpleUrlHandlerMappingConfig.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/config/SimpleUrlHandlerMappingConfig.java @@ -18,7 +18,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; public class SimpleUrlHandlerMappingConfig { @Bean - public ViewResolver viewResolver() { + public ViewResolver viewResolverSimpleMappingConfig() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/"); viewResolver.setSuffix(".jsp"); @@ -29,13 +29,13 @@ public class SimpleUrlHandlerMappingConfig { public SimpleUrlHandlerMapping simpleUrlHandlerMapping() { SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping(); Map urlMap = new HashMap<>(); - urlMap.put("/simpleUrlWelcome", welcome()); + urlMap.put("/simpleUrlWelcome", welcomeSimpleMappingConfig()); simpleUrlHandlerMapping.setUrlMap(urlMap); return simpleUrlHandlerMapping; } @Bean - public WelcomeController welcome() { + public WelcomeController welcomeSimpleMappingConfig() { return new WelcomeController(); } diff --git a/spring-mvc-java/src/test/java/com/baeldung/handlermappings/BeanNameMappingConfigIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/handlermappings/BeanNameMappingConfigIntegrationTest.java similarity index 100% rename from spring-mvc-java/src/test/java/com/baeldung/handlermappings/BeanNameMappingConfigIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/handlermappings/BeanNameMappingConfigIntegrationTest.java diff --git a/spring-mvc-java/src/test/java/com/baeldung/handlermappings/HandlerMappingDefaultConfigIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/handlermappings/HandlerMappingDefaultConfigIntegrationTest.java similarity index 100% rename from spring-mvc-java/src/test/java/com/baeldung/handlermappings/HandlerMappingDefaultConfigIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/handlermappings/HandlerMappingDefaultConfigIntegrationTest.java diff --git a/spring-mvc-java/src/test/java/com/baeldung/handlermappings/HandlerMappingPriorityConfigIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/handlermappings/HandlerMappingPriorityConfigIntegrationTest.java similarity index 100% rename from spring-mvc-java/src/test/java/com/baeldung/handlermappings/HandlerMappingPriorityConfigIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/handlermappings/HandlerMappingPriorityConfigIntegrationTest.java diff --git a/spring-mvc-java/src/test/java/com/baeldung/handlermappings/SimpleUrlMappingConfigIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/handlermappings/SimpleUrlMappingConfigIntegrationTest.java similarity index 100% rename from spring-mvc-java/src/test/java/com/baeldung/handlermappings/SimpleUrlMappingConfigIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/handlermappings/SimpleUrlMappingConfigIntegrationTest.java diff --git a/spring-mvc-java/src/test/resources/BeanNameUrlHandlerMappingConfig.xml b/spring-mvc-basics/src/test/resources/BeanNameUrlHandlerMappingConfig.xml similarity index 100% rename from spring-mvc-java/src/test/resources/BeanNameUrlHandlerMappingConfig.xml rename to spring-mvc-basics/src/test/resources/BeanNameUrlHandlerMappingConfig.xml diff --git a/spring-mvc-java/src/test/resources/ControllerClassNameHandlerMappingConfig.xml b/spring-mvc-basics/src/test/resources/ControllerClassNameHandlerMappingConfig.xml similarity index 100% rename from spring-mvc-java/src/test/resources/ControllerClassNameHandlerMappingConfig.xml rename to spring-mvc-basics/src/test/resources/ControllerClassNameHandlerMappingConfig.xml diff --git a/spring-mvc-java/src/test/resources/HandlerMappingConfiguringPriorities.xml b/spring-mvc-basics/src/test/resources/HandlerMappingConfiguringPriorities.xml similarity index 100% rename from spring-mvc-java/src/test/resources/HandlerMappingConfiguringPriorities.xml rename to spring-mvc-basics/src/test/resources/HandlerMappingConfiguringPriorities.xml diff --git a/spring-mvc-java/src/test/resources/SimpleUrlHandlerMappingConfig.xml b/spring-mvc-basics/src/test/resources/SimpleUrlHandlerMappingConfig.xml similarity index 100% rename from spring-mvc-java/src/test/resources/SimpleUrlHandlerMappingConfig.xml rename to spring-mvc-basics/src/test/resources/SimpleUrlHandlerMappingConfig.xml diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index c670b153cf..8ba9b5fd1e 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -17,7 +17,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Circular Dependencies in Spring](http://www.baeldung.com/circular-dependencies-in-spring) - [Introduction to HtmlUnit](http://www.baeldung.com/htmlunit) - [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) -- [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) - [Upload and Display Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) - [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) From f13b1e78ef0528eabf0b0903b284070122600324 Mon Sep 17 00:00:00 2001 From: gpq5 Date: Sat, 22 Jun 2019 22:17:12 +0530 Subject: [PATCH 08/74] [BAEL-3002] Comparing 2 JSON objects with Jackson --- .../json/compare/JsonCompareUnitTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java diff --git a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java new file mode 100644 index 0000000000..02f6726901 --- /dev/null +++ b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.jackson.json.compare; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Comparator; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.NumericNode; + +public class JsonCompareUnitTest { + + @Test + public void givenTwoSameJsonDataObjects_whenCompared_thenAreEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String jsonString1 = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\",\"k4\":\"v4\"}"; + String jsonString2 = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\",\"k4\":\"v4\"}"; + JsonNode actualObj1 = mapper.readTree(jsonString1); + JsonNode actualObj2 = mapper.readTree(jsonString2); + + assertTrue(actualObj1.equals(actualObj2)); + + } + + @Test + public void givenTwoJsonDataObjects_whenComparedUsingCustomComparator_thenEqual() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + + String jsonString1 = "{\"k1\": 5,\"k2\":9191}"; + String jsonString2 = "{\"k1\": 5.0,\"k2\":9191}"; + JsonNode actualObj1 = mapper.readTree(jsonString1); + JsonNode actualObj2 = mapper.readTree(jsonString2); + + assertFalse(actualObj1.equals(actualObj2)); + + Comparator cmp = new Comparator() { + @Override + public int compare(JsonNode o1, JsonNode o2) { + if (o1.equals(o2)) { + return 0; + } + if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) { + double d1 = ((NumericNode) o1).asDouble(); + double d2 = ((NumericNode) o2).asDouble(); + if (d1 == d2) { + return 0; + } + } + return 1; + } + }; + + assertTrue(actualObj1.equals(cmp, actualObj2)); + + } + +} From 0eeb8a37f5d6fa5870f583e4e66b879895102927 Mon Sep 17 00:00:00 2001 From: gpq5 Date: Sun, 23 Jun 2019 08:58:20 +0530 Subject: [PATCH 09/74] added additional examples --- .../json/compare/JsonCompareUnitTest.java | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java index 02f6726901..100f999d10 100644 --- a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java +++ b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java @@ -18,10 +18,39 @@ public class JsonCompareUnitTest { public void givenTwoSameJsonDataObjects_whenCompared_thenAreEqual() throws IOException { ObjectMapper mapper = new ObjectMapper(); - String jsonString1 = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\",\"k4\":\"v4\"}"; - String jsonString2 = "{\"k1\":\"v1\",\"k2\":\"v2\",\"k3\":\"v3\",\"k4\":\"v4\"}"; - JsonNode actualObj1 = mapper.readTree(jsonString1); - JsonNode actualObj2 = mapper.readTree(jsonString2); + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34 }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34 }}"; + + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + assertTrue(actualObj1.equals(actualObj2)); + + } + + @Test + public void givenTwoSameNestedJsonDataObjects_whenCompared_thenAreEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34,\n" + "\"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34,\n" + "\"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; + + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + assertTrue(actualObj1.equals(actualObj2)); + + } + + @Test + public void givenTwoSameListJsonDataObjects_whenCompared_thenAreEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}"; + + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); assertTrue(actualObj1.equals(actualObj2)); @@ -31,12 +60,11 @@ public class JsonCompareUnitTest { public void givenTwoJsonDataObjects_whenComparedUsingCustomComparator_thenEqual() throws Exception { ObjectMapper mapper = new ObjectMapper(); - String jsonString1 = "{\"k1\": 5,\"k2\":9191}"; - String jsonString2 = "{\"k1\": 5.0,\"k2\":9191}"; - JsonNode actualObj1 = mapper.readTree(jsonString1); - JsonNode actualObj2 = mapper.readTree(jsonString2); + String s1 = "{\"name\": \"John\",\"score\":5.0}"; + String s2 = "{\"name\": \"John\",\"score\":5}"; + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); - assertFalse(actualObj1.equals(actualObj2)); Comparator cmp = new Comparator() { @Override @@ -55,6 +83,7 @@ public class JsonCompareUnitTest { } }; + assertFalse(actualObj1.equals(actualObj2)); assertTrue(actualObj1.equals(cmp, actualObj2)); } From 212326a754c4f9849bb6ed114b5d70c1df84fe4d Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Sun, 23 Jun 2019 13:50:50 +0800 Subject: [PATCH 10/74] BAEL-2910 MockMvc Kotlin DSL * configured spring repo in the 'parent-kotlin' model to allow using spring's milestone artifacts * configured jackson kotlin module in the 'parent-kotlin' to allow easy use of kotlin data classes with jackson * switched spring-mvc-kotlin from explicit spring dependencies to spring-boot * mockmvc dsl article's source and tests --- parent-kotlin/pom.xml | 11 +++- spring-mvc-kotlin/pom.xml | 12 ++-- .../kotlin/mockmvc/MockMvcController.kt | 26 ++++++++ .../baeldung/kotlin/mockmvc/MockMvcModel.kt | 10 +++ .../kotlin/mockmvc/MockMvcControllerTest.kt | 61 +++++++++++++++++++ 5 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt create mode 100644 spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt create mode 100644 spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt diff --git a/parent-kotlin/pom.xml b/parent-kotlin/pom.xml index 6f7fe6c102..d993fad3c6 100644 --- a/parent-kotlin/pom.xml +++ b/parent-kotlin/pom.xml @@ -26,6 +26,11 @@ kotlin-eap http://dl.bintray.com/kotlin/kotlin-eap + + spring-milestone + Spring Milestone Repository + http://repo.spring.io/milestone + @@ -40,7 +45,7 @@ org.springframework.boot spring-boot-dependencies - 2.0.1.RELEASE + 2.2.0.M4 pom import @@ -80,6 +85,10 @@ ktor-gson ${ktor.io.version} + + com.fasterxml.jackson.module + jackson-module-kotlin + org.jetbrains.kotlin diff --git a/spring-mvc-kotlin/pom.xml b/spring-mvc-kotlin/pom.xml index fc76f58727..fb1f242644 100644 --- a/spring-mvc-kotlin/pom.xml +++ b/spring-mvc-kotlin/pom.xml @@ -15,12 +15,12 @@ - org.springframework - spring-web + org.springframework.boot + spring-boot-starter-web - org.springframework - spring-webmvc + org.springframework.boot + spring-boot-starter-json org.thymeleaf @@ -46,8 +46,8 @@ test - org.springframework - spring-test + org.springframework.boot + spring-boot-starter-test test diff --git a/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt new file mode 100644 index 0000000000..68ab5f31a6 --- /dev/null +++ b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcController.kt @@ -0,0 +1,26 @@ +package com.baeldung.kotlin.mockmvc + +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestMethod +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/mockmvc") +class MockMvcController { + + @RequestMapping(value = ["/validate"], method = [RequestMethod.POST], produces = [MediaType.APPLICATION_JSON_VALUE]) + fun validate(@RequestBody request: Request): Response { + val error = if (request.name.first == "admin") { + null + } else { + ERROR + } + return Response(error) + } + + companion object { + const val ERROR = "invalid user" + } +} \ No newline at end of file diff --git a/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt new file mode 100644 index 0000000000..3231b6f186 --- /dev/null +++ b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mockmvc/MockMvcModel.kt @@ -0,0 +1,10 @@ +package com.baeldung.kotlin.mockmvc + +import com.fasterxml.jackson.annotation.JsonInclude + +data class Name(val first: String, val last: String) + +data class Request(val name: Name) + +@JsonInclude(JsonInclude.Include.NON_NULL) +data class Response(val error: String?) \ No newline at end of file diff --git a/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt b/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt new file mode 100644 index 0000000000..802cd4c1e7 --- /dev/null +++ b/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/mockmvc/MockMvcControllerTest.kt @@ -0,0 +1,61 @@ +package com.baeldung.kotlin.mockmvc + +import com.fasterxml.jackson.databind.ObjectMapper +import org.junit.Test +import org.junit.runner.RunWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity.status +import org.springframework.test.context.junit4.SpringRunner +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.post +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders +import org.springframework.test.web.servlet.result.MockMvcResultHandlers +import org.springframework.test.web.servlet.result.MockMvcResultMatchers + +@RunWith(SpringRunner::class) +@WebMvcTest +class MockMvcControllerTest { + + @Autowired lateinit var mockMvc: MockMvc + @Autowired lateinit var mapper: ObjectMapper + + @Test + fun `when supported user is given then raw MockMvc-based validation is successful`() { + mockMvc.perform(MockMvcRequestBuilders + .post("/mockmvc/validate") + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(Request(Name("admin", ""))))) + .andExpect(MockMvcResultMatchers.status().isOk) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.content().string("{}")) + } + + @Test + fun `when supported user is given then kotlin DSL-based validation is successful`() { + doTest(Request(Name("admin", "")), Response(null)) + } + + @Test + fun `when unsupported user is given then validation is failed`() { + doTest(Request(Name("some-name", "some-surname")), Response(MockMvcController.ERROR)) + } + + private fun doTest(input: Request, expectation: Response) { + mockMvc.post("/mockmvc/validate") { + contentType = MediaType.APPLICATION_JSON + content = mapper.writeValueAsString(input) + accept = MediaType.APPLICATION_JSON + }.andExpect { + status { isOk } + content { contentType(MediaType.APPLICATION_JSON) } + content { json(mapper.writeValueAsString(expectation)) } + } + } +} + +@SpringBootApplication +class MockMvcApplication \ No newline at end of file From 706035468b8992f58fd79ecc3d47311f92dd8104 Mon Sep 17 00:00:00 2001 From: gpq5 Date: Sun, 23 Jun 2019 12:35:44 +0530 Subject: [PATCH 11/74] Minor fixes --- .../jackson/json/compare/JsonCompareUnitTest.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java index 100f999d10..05b89abc09 100644 --- a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java +++ b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java @@ -18,8 +18,8 @@ public class JsonCompareUnitTest { public void givenTwoSameJsonDataObjects_whenCompared_thenAreEqual() throws IOException { ObjectMapper mapper = new ObjectMapper(); - String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34 }}"; - String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34 }}"; + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\", \"age\": 34 }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"age\": 34, \"fullName\": \"John Miles\" }}"; JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); @@ -29,11 +29,11 @@ public class JsonCompareUnitTest { } @Test - public void givenTwoSameNestedJsonDataObjects_whenCompared_thenAreEqual() throws IOException { + public void givenTwoSameNestedJsonDataObjects_whenCompared_thenEqual() throws IOException { ObjectMapper mapper = new ObjectMapper(); - String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34,\n" + "\"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; - String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34,\n" + "\"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; + String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; + String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}"; JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); @@ -43,7 +43,7 @@ public class JsonCompareUnitTest { } @Test - public void givenTwoSameListJsonDataObjects_whenCompared_thenAreEqual() throws IOException { + public void givenTwoSameListJsonDataObjects_whenCompared_thenEqual() throws IOException { ObjectMapper mapper = new ObjectMapper(); String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}"; @@ -57,7 +57,7 @@ public class JsonCompareUnitTest { } @Test - public void givenTwoJsonDataObjects_whenComparedUsingCustomComparator_thenEqual() throws Exception { + public void givenTwoJsonDataObjects_whenComparedUsingCustomComparator_thenEqual() throws IOException { ObjectMapper mapper = new ObjectMapper(); String s1 = "{\"name\": \"John\",\"score\":5.0}"; @@ -65,7 +65,6 @@ public class JsonCompareUnitTest { JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); - Comparator cmp = new Comparator() { @Override public int compare(JsonNode o1, JsonNode o2) { From 3d50c203a630fb42652ad1898e50b0d50eaa2e70 Mon Sep 17 00:00:00 2001 From: gpq5 Date: Fri, 28 Jun 2019 10:15:05 +0530 Subject: [PATCH 12/74] made changes as per review comments --- .../json/compare/JsonCompareUnitTest.java | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java index 05b89abc09..2f2c18e248 100644 --- a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java +++ b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java @@ -1,6 +1,7 @@ package com.baeldung.jackson.json.compare; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; @@ -24,7 +25,7 @@ public class JsonCompareUnitTest { JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); - assertTrue(actualObj1.equals(actualObj2)); + assertEquals(actualObj1, actualObj2); } @@ -38,7 +39,7 @@ public class JsonCompareUnitTest { JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); - assertTrue(actualObj1.equals(actualObj2)); + assertEquals(actualObj1, actualObj2); } @@ -52,7 +53,7 @@ public class JsonCompareUnitTest { JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); - assertTrue(actualObj1.equals(actualObj2)); + assertEquals(actualObj1, actualObj2); } @@ -65,26 +66,27 @@ public class JsonCompareUnitTest { JsonNode actualObj1 = mapper.readTree(s1); JsonNode actualObj2 = mapper.readTree(s2); - Comparator cmp = new Comparator() { - @Override - public int compare(JsonNode o1, JsonNode o2) { - if (o1.equals(o2)) { - return 0; - } - if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) { - double d1 = ((NumericNode) o1).asDouble(); - double d2 = ((NumericNode) o2).asDouble(); - if (d1 == d2) { - return 0; - } - } - return 1; - } - }; + NumericNodeComparator cmp = new NumericNodeComparator(); - assertFalse(actualObj1.equals(actualObj2)); + assertNotEquals(actualObj1, actualObj2); assertTrue(actualObj1.equals(cmp, actualObj2)); } - + + public class NumericNodeComparator implements Comparator { + @Override + public int compare(JsonNode o1, JsonNode o2) { + if (o1.equals(o2)) { + return 0; + } + if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) { + Double d1 = ((NumericNode) o1).asDouble(); + Double d2 = ((NumericNode) o2).asDouble(); + if (d1.equals(d2)) { + return 0; + } + } + return 1; + } + } } From 6af16b82fb95397aac602ccd08ec3bcd5e7ed541 Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Sat, 29 Jun 2019 21:37:40 +0300 Subject: [PATCH 13/74] BAEL-2995 - possible lossy conversion --- .../ConversionTechniquesUnitTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 java-numbers/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java diff --git a/java-numbers/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java b/java-numbers/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java new file mode 100644 index 0000000000..9ed714e853 --- /dev/null +++ b/java-numbers/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.lossyconversion; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; + +public class ConversionTechniquesUnitTest { + + @Test + public void testPrimitiveConversion() { + + double doubleNum = 15.6; + int integerNum = (int) doubleNum; + + assertEquals(integerNum, 15); + } + + @Test + public void testWrapperConversion() { + + Double doubleNum = 10.3; + double dbl = doubleNum.doubleValue(); + int intgr = (int) dbl; + Integer intNum = Integer.valueOf(intgr); + + assertTrue(intNum == 10); + } + + @Test + public void testWrapperToPrimitiveConversion() { + + Float floatNum = 17.564f; + long longNum = floatNum.longValue(); + + assertEquals(longNum, 17l); + + Double doubleNum = 15.9999; + int intNum = doubleNum.intValue(); + + assertEquals(intNum, 15); + + longNum = Math.round(doubleNum); + + assertEquals(longNum, 16); + } + + @Test + public void testWrapperToPrimitiveConversionUsingMathRound() { + + Double doubleNum = 15.9999; + long longNum = Math.round(doubleNum); + + assertEquals(longNum, 16); + } +} From bc39e680a2d978b11fedaf27021ec860b7c8d126 Mon Sep 17 00:00:00 2001 From: eelhazati Date: Sun, 30 Jun 2019 16:45:00 +0100 Subject: [PATCH 14/74] OAuth2 framework implementation. --- .../oauth2-authorization-server/pom.xml | 72 ++++++ .../server/OAuth2ServerApplication.java | 8 + .../authorization/server/PEMKeyUtils.java | 17 ++ .../server/api/AuthorizationEndpoint.java | 185 ++++++++++++++++ .../authorization/server/api/JWKEndpoint.java | 38 ++++ .../server/api/TokenEndpoint.java | 86 +++++++ .../AuthorizationCodeGrantTypeHandler.java | 99 +++++++++ .../AuthorizationGrantTypeHandler.java | 8 + .../server/model/AppDataRepository.java | 27 +++ .../server/model/AuthorizationCode.java | 73 ++++++ .../authorization/server/model/Client.java | 62 ++++++ .../authorization/server/model/User.java | 58 +++++ .../server/security/UserIdentityStore.java | 37 ++++ .../server/web/AuthorizationEndpoint.java | 209 ++++++++++++++++++ .../server/web/TokenEndpoint.java | 70 ++++++ .../src/main/liberty/config/server.xml | 32 +++ .../META-INF/microprofile-config.properties | 2 + .../main/resources/META-INF/persistence.xml | 14 ++ .../main/resources/META-INF/private-key.pem | 28 +++ .../main/resources/META-INF/public-key.pem | 9 + .../src/main/resources/data.sql | 3 + .../src/main/webapp/WEB-INF/beans.xml | 6 + .../src/main/webapp/authorize.jsp | 54 +++++ .../src/main/webapp/error.jsp | 25 +++ .../src/main/webapp/login-error.jsp | 0 .../src/main/webapp/login.jsp | 49 ++++ oauth2-framework-impl/oauth2-client/pom.xml | 28 +++ .../client/AuthorizationCodeServlet.java | 39 ++++ .../oauth2/client/CallbackServlet.java | 76 +++++++ .../oauth2/client/DownstreamCallServlet.java | 49 ++++ .../src/main/liberty/config/server.xml | 19 ++ .../META-INF/microprofile-config.properties | 12 + .../src/main/webapp/WEB-INF/beans.xml | 6 + .../src/main/webapp/WEB-INF/web.xml | 5 + .../oauth2-client/src/main/webapp/index.jsp | 97 ++++++++ .../oauth2-resource-server/pom.xml | 40 ++++ .../OAuth2ResourceServerApplication.java | 13 ++ .../server/secure/ProtectedResource.java | 38 ++++ .../src/main/liberty/config/server.xml | 20 ++ .../META-INF/microprofile-config.properties | 2 + .../main/resources/META-INF/public-key.pem | 9 + .../src/main/webapp/WEB-INF/beans.xml | 6 + .../src/main/webapp/index.html | 37 ++++ oauth2-framework-impl/pom.xml | 93 ++++++++ 44 files changed, 1860 insertions(+) create mode 100644 oauth2-framework-impl/oauth2-authorization-server/pom.xml create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/OAuth2ServerApplication.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/PEMKeyUtils.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/JWKEndpoint.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationGrantTypeHandler.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AppDataRepository.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AuthorizationCode.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/Client.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/User.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/security/UserIdentityStore.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/AuthorizationEndpoint.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/TokenEndpoint.java create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/liberty/config/server.xml create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/microprofile-config.properties create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/persistence.xml create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/private-key.pem create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/public-key.pem create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/resources/data.sql create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/WEB-INF/beans.xml create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/error.jsp create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/login-error.jsp create mode 100644 oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/login.jsp create mode 100644 oauth2-framework-impl/oauth2-client/pom.xml create mode 100644 oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/AuthorizationCodeServlet.java create mode 100644 oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java create mode 100644 oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/DownstreamCallServlet.java create mode 100644 oauth2-framework-impl/oauth2-client/src/main/liberty/config/server.xml create mode 100644 oauth2-framework-impl/oauth2-client/src/main/resources/META-INF/microprofile-config.properties create mode 100644 oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/beans.xml create mode 100644 oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/web.xml create mode 100644 oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp create mode 100644 oauth2-framework-impl/oauth2-resource-server/pom.xml create mode 100644 oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/OAuth2ResourceServerApplication.java create mode 100644 oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/secure/ProtectedResource.java create mode 100644 oauth2-framework-impl/oauth2-resource-server/src/main/liberty/config/server.xml create mode 100644 oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/microprofile-config.properties create mode 100644 oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/public-key.pem create mode 100644 oauth2-framework-impl/oauth2-resource-server/src/main/webapp/WEB-INF/beans.xml create mode 100644 oauth2-framework-impl/oauth2-resource-server/src/main/webapp/index.html create mode 100644 oauth2-framework-impl/pom.xml diff --git a/oauth2-framework-impl/oauth2-authorization-server/pom.xml b/oauth2-framework-impl/oauth2-authorization-server/pom.xml new file mode 100644 index 0000000000..8db2150558 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + + oauth2-authorization-server + war + + + com.baeldung.oauth2 + oauth2-framework-impl + 1.0-SNAPSHOT + + + + 1.4.199 + 9080 + 9443 + + + + + com.nimbusds + nimbus-jose-jwt + 7.3 + + + org.bouncycastle + bcprov-jdk15on + 1.62 + + + org.bouncycastle + bcpkix-jdk15on + 1.62 + + + + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-h2-dependency + package + + copy + + + + + + + com.h2database + h2 + ${h2.version} + jar + ${project.build.directory}/liberty/wlp/usr/shared/resources/ + + + + + + + + diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/OAuth2ServerApplication.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/OAuth2ServerApplication.java new file mode 100644 index 0000000000..62d6b04464 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/OAuth2ServerApplication.java @@ -0,0 +1,8 @@ +package com.baeldung.oauth2.authorization.server; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +@ApplicationPath("/") +public class OAuth2ServerApplication extends Application { +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/PEMKeyUtils.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/PEMKeyUtils.java new file mode 100644 index 0000000000..dab57b91a7 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/PEMKeyUtils.java @@ -0,0 +1,17 @@ +package com.baeldung.oauth2.authorization.server; + +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static java.lang.Thread.currentThread; + + +public class PEMKeyUtils { + + public static String readKeyAsString(String keyLocation) throws Exception { + URI uri = currentThread().getContextClassLoader().getResource(keyLocation).toURI(); + byte[] byteArray = Files.readAllBytes(Paths.get(uri)); + return new String(byteArray); + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java new file mode 100644 index 0000000000..10e78a2dfd --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/AuthorizationEndpoint.java @@ -0,0 +1,185 @@ +package com.baeldung.oauth2.authorization.server.api; + +import com.baeldung.oauth2.authorization.server.handler.AuthorizationGrantTypeHandler; +import com.baeldung.oauth2.authorization.server.model.AppDataRepository; +import com.baeldung.oauth2.authorization.server.model.AuthorizationCode; +import com.baeldung.oauth2.authorization.server.model.Client; +import com.baeldung.oauth2.authorization.server.model.User; + +import javax.annotation.security.RolesAllowed; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Instance; +import javax.enterprise.inject.literal.NamedLiteral; +import javax.inject.Inject; +import javax.json.JsonObject; +import javax.security.enterprise.SecurityContext; +import javax.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition; +import javax.security.enterprise.authentication.mechanism.http.LoginToContinue; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.*; +import javax.ws.rs.core.*; +import java.io.IOException; +import java.net.URI; +import java.security.Principal; +import java.time.LocalDateTime; +import java.util.*; + +@FormAuthenticationMechanismDefinition( + loginToContinue = @LoginToContinue(loginPage = "/login.jsp", errorPage = "/login.jsp") +) +@RolesAllowed("USER") +@RequestScoped +@Path("authorize") +public class AuthorizationEndpoint { + + @Inject + private SecurityContext securityContext; + + @Inject + private AppDataRepository appDataRepository; + + @Inject + Instance authorizationGrantTypeHandlers; + + @GET + @Produces(MediaType.TEXT_HTML) + public Response doGet(@Context HttpServletRequest request, + @Context HttpServletResponse response, + @Context UriInfo uriInfo) throws ServletException, IOException { + MultivaluedMap params = uriInfo.getQueryParameters(); + Principal principal = securityContext.getCallerPrincipal(); + + //error about redirect_uri && client_id ==> forward user, thus to error.jsp. + //otherwise ==> sendRedirect redirect_uri?error=error&error_description=error_description + //1. client_id + String clientId = params.getFirst("client_id"); + if (clientId == null || clientId.isEmpty()) { + return informUserAboutError(request, response, "Invalid client_id :" + clientId); + } + Client client = appDataRepository.getClient(clientId); + if (client == null) { + return informUserAboutError(request, response, "Invalid client_id :" + clientId); + } + //2. Client Authorized Grant Type + String clientError = ""; + if (client.getAuthorizedGrantTypes() != null && !client.getAuthorizedGrantTypes().contains("authorization_code")) { + return informUserAboutError(request, response, "Authorization Grant type, authorization_code, is not allowed for this client :" + clientId); + } + + //3. redirectUri + String redirectUri = params.getFirst("redirect_uri"); + if (client.getRedirectUri() != null && !client.getRedirectUri().isEmpty()) { + if (redirectUri != null && !redirectUri.isEmpty() && !client.getRedirectUri().equals(redirectUri)) { + //sould be in the client.redirectUri + return informUserAboutError(request, response, "redirect_uri is pre-registred and should match"); + } + redirectUri = client.getRedirectUri(); + params.putSingle("resolved_redirect_uri", redirectUri); + } else { + if (redirectUri == null || redirectUri.isEmpty()) { + return informUserAboutError(request, response, "redirect_uri is not pre-registred and should be provided"); + } + params.putSingle("resolved_redirect_uri", redirectUri); + } + request.setAttribute("client", client); + + //4. response_type + String responseType = params.getFirst("response_type"); + if (!"code".equals(responseType) && !"token".equals(responseType)) { + //error = "invalid_grant :" + responseType + ", response_type params should be code or token:"; + //return informUserAboutError(error); + } + + //Save params in session + request.getSession().setAttribute("ORIGINAL_PARAMS", params); + + //4.scope: Optional + String requestedScope = request.getParameter("scope"); + if (requestedScope == null || requestedScope.isEmpty()) { + requestedScope = client.getScope(); + } + User user = appDataRepository.getUser(principal.getName()); + String allowedScopes = checkUserScopes(user.getScopes(), requestedScope); + request.setAttribute("scopes", allowedScopes); + + request.getRequestDispatcher("/authorize.jsp").forward(request, response); + return null; + } + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_HTML) + public Response doPost(@Context HttpServletRequest request, + @Context HttpServletResponse response, + MultivaluedMap params) throws Exception { + MultivaluedMap originalParams = (MultivaluedMap) request.getSession().getAttribute("ORIGINAL_PARAMS"); + if (originalParams == null) { + return informUserAboutError(request, response, "No pending authorization request."); + } + String redirectUri = originalParams.getFirst("resolved_redirect_uri"); + StringBuilder sb = new StringBuilder(redirectUri); + + String approbationStatus = params.getFirst("approbation_status"); + if ("NO".equals(approbationStatus)) { + URI location = UriBuilder.fromUri(sb.toString()) + .queryParam("error", "User doesn't approved the request.") + .queryParam("error_description", "User doesn't approved the request.") + .build(); + return Response.seeOther(location).build(); + } + //==> YES + List approvedScopes = params.get("scope"); + if (approvedScopes == null || approvedScopes.isEmpty()) { + URI location = UriBuilder.fromUri(sb.toString()) + .queryParam("error", "User doesn't approved the request.") + .queryParam("error_description", "User doesn't approved the request.") + .build(); + return Response.seeOther(location).build(); + } + + String responseType = originalParams.getFirst("response_type"); + String clientId = originalParams.getFirst("client_id"); + if ("code".equals(responseType)) { + String userId = securityContext.getCallerPrincipal().getName(); + AuthorizationCode authorizationCode = new AuthorizationCode(); + authorizationCode.setClientId(clientId); + authorizationCode.setUserId(userId); + authorizationCode.setApprovedScopes(String.join(" ", approvedScopes)); + authorizationCode.setExpirationDate(LocalDateTime.now().plusMinutes(10)); + authorizationCode.setRedirectUri(redirectUri); + appDataRepository.save(authorizationCode); + String code = authorizationCode.getCode(); + sb.append("?code=").append(code); + } else { + //Implicit: responseType=token + AuthorizationGrantTypeHandler authorizationGrantTypeHandler = authorizationGrantTypeHandlers.select(NamedLiteral.of("implicit")).get(); + JsonObject tokenResponse = authorizationGrantTypeHandler.createAccessToken(clientId, params); + sb.append("#access_token=").append(tokenResponse.getString("access_token")) + .append("&token_type=").append(tokenResponse.getString("token_type")) + .append("&scope=").append(tokenResponse.getString("scope")); + } + String state = originalParams.getFirst("state"); + if (state != null) { + sb.append("&state=").append(state); + } + return Response.seeOther(UriBuilder.fromUri(sb.toString()).build()).build(); + } + + private String checkUserScopes(String userScopes, String requestedScope) { + Set allowedScopes = new LinkedHashSet<>(); + Set rScopes = new HashSet(Arrays.asList(requestedScope.split(" "))); + Set uScopes = new HashSet(Arrays.asList(userScopes.split(" "))); + for (String scope : uScopes) { + if (rScopes.contains(scope)) allowedScopes.add(scope); + } + return String.join(" ", allowedScopes); + } + + private Response informUserAboutError(HttpServletRequest request, HttpServletResponse response, String error) throws ServletException, IOException { + request.setAttribute("error", error); + request.getRequestDispatcher("/error.jsp").forward(request, response); + return null; + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/JWKEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/JWKEndpoint.java new file mode 100644 index 0000000000..9d38c823b9 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/JWKEndpoint.java @@ -0,0 +1,38 @@ +package com.baeldung.oauth2.authorization.server.api; + +import com.baeldung.oauth2.authorization.server.PEMKeyUtils; +import com.nimbusds.jose.jwk.JWK; +import org.eclipse.microprofile.config.Config; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Arrays; + +@Path("jwk") +@ApplicationScoped +public class JWKEndpoint { + + @Inject + private Config config; + + @GET + public Response getKey(@QueryParam("format") String format) throws Exception { + if (format != null && !Arrays.asList("jwk", "pem").contains(format)) { + return Response.status(Response.Status.BAD_REQUEST).entity("Public Key Format should be : jwk or pem").build(); + } + String verificationkey = config.getValue("verificationkey", String.class); + String pemEncodedRSAPublicKey = PEMKeyUtils.readKeyAsString(verificationkey); + if (format == null || format.equals("jwk")) { + JWK jwk = JWK.parseFromPEMEncodedObjects(pemEncodedRSAPublicKey); + return Response.ok(jwk.toJSONString()).type(MediaType.APPLICATION_JSON).build(); + } else if (format.equals("pem")) { + return Response.ok(pemEncodedRSAPublicKey).build(); + } + return null; + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java new file mode 100644 index 0000000000..f39bb2ea2d --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/api/TokenEndpoint.java @@ -0,0 +1,86 @@ +package com.baeldung.oauth2.authorization.server.api; + +import com.baeldung.oauth2.authorization.server.handler.AuthorizationGrantTypeHandler; +import com.baeldung.oauth2.authorization.server.model.AppDataRepository; +import com.baeldung.oauth2.authorization.server.model.Client; +import com.nimbusds.jose.JOSEException; + +import javax.enterprise.inject.Instance; +import javax.enterprise.inject.literal.NamedLiteral; +import javax.inject.Inject; +import javax.json.Json; +import javax.json.JsonObject; +import javax.ws.rs.*; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +@Path("token") +public class TokenEndpoint { + + List supportedGrantTypes = Collections.singletonList("authorization_code"); + + @Inject + private AppDataRepository appDataRepository; + + @Inject + Instance authorizationGrantTypeHandlers; + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response token(MultivaluedMap params, + @HeaderParam(HttpHeaders.AUTHORIZATION) String authHeader) throws JOSEException { + + //Check grant_type params + String grantType = params.getFirst("grant_type"); + Objects.requireNonNull(grantType, "grant_type params is required"); + if (!supportedGrantTypes.contains(grantType)) { + JsonObject error = Json.createObjectBuilder() + .add("error", "unsupported_grant_type") + .add("error_description", "grant type should be one of :" + supportedGrantTypes) + .build(); + return Response.status(Response.Status.BAD_REQUEST) + .entity(error).build(); + + } + + //Client Authentication + String[] clientCredentials = extract(authHeader); + String clientId = clientCredentials[0]; + String clientSecret = clientCredentials[1]; + Client client = appDataRepository.getClient(clientId); + if (client == null || clientSecret == null || !clientSecret.equals(client.getClientSecret())) { + JsonObject error = Json.createObjectBuilder() + .add("error", "invalid_client") + .build(); + return Response.status(Response.Status.UNAUTHORIZED) + .entity(error).build(); + } + + AuthorizationGrantTypeHandler authorizationGrantTypeHandler = authorizationGrantTypeHandlers.select(NamedLiteral.of(grantType)).get(); + JsonObject tokenResponse = null; + try { + tokenResponse = authorizationGrantTypeHandler.createAccessToken(clientId, params); + } catch (Exception e) { + e.printStackTrace(); + } + + return Response.ok(tokenResponse) + .header("Cache-Control", "no-store") + .header("Pragma", "no-cache") + .build(); + } + + private String[] extract(String authHeader) { + if (authHeader != null && authHeader.startsWith("Basic ")) { + return new String(Base64.getDecoder().decode(authHeader.substring(6))).split(":"); + } + return null; + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java new file mode 100644 index 0000000000..889c7fcea2 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationCodeGrantTypeHandler.java @@ -0,0 +1,99 @@ +package com.baeldung.oauth2.authorization.server.handler; + +import com.baeldung.oauth2.authorization.server.PEMKeyUtils; +import com.baeldung.oauth2.authorization.server.model.AuthorizationCode; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jose.jwk.JWK; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import org.eclipse.microprofile.config.Config; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.json.Json; +import javax.json.JsonObject; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MultivaluedMap; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Date; +import java.util.UUID; + +@Named("authorization_code") +public class AuthorizationCodeGrantTypeHandler implements AuthorizationGrantTypeHandler { + + @PersistenceContext + private EntityManager entityManager; + + @Inject + private Config config; + + @Override + public JsonObject createAccessToken(String clientId, MultivaluedMap params) throws Exception { + //1. code is required + String code = params.getFirst("code"); + if (code == null || "".equals(code)) { + throw new WebApplicationException("invalid_grant"); + } + AuthorizationCode authorizationCode = entityManager.find(AuthorizationCode.class, code); + if (!authorizationCode.getExpirationDate().isAfter(LocalDateTime.now())) { + throw new WebApplicationException("code Expired !"); + } + String redirectUri = params.getFirst("redirect_uri"); + //redirecturi match + if (authorizationCode.getRedirectUri() != null && !authorizationCode.getRedirectUri().equals(redirectUri)) { + //redirectUri params should be the same as the requested redirectUri. + throw new WebApplicationException("invalid_grant"); + } + //client match + if (!clientId.equals(authorizationCode.getClientId())) { + throw new WebApplicationException("invalid_grant"); + } + + //JWT Header + JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT).build(); + + Instant now = Instant.now(); + Long expiresInMin = 30L; + Date expiresIn = Date.from(now.plus(expiresInMin, ChronoUnit.MINUTES)); + + //3. JWT Payload or claims + JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder() + .issuer("http://localhost:9080") + .subject(authorizationCode.getUserId()) + .claim("upn", authorizationCode.getUserId()) + .audience("http://localhost:9280") + .claim("scope", authorizationCode.getApprovedScopes()) + .claim("groups", Arrays.asList(authorizationCode.getApprovedScopes().split(" "))) + .expirationTime(expiresIn) // expires in 30 minutes + .notBeforeTime(Date.from(now)) + .issueTime(Date.from(now)) + .jwtID(UUID.randomUUID().toString()) + .build(); + SignedJWT signedJWT = new SignedJWT(jwsHeader, jwtClaims); + + //4. Signing + String signingkey = config.getValue("signingkey", String.class); + String pemEncodedRSAPrivateKey = PEMKeyUtils.readKeyAsString(signingkey); + RSAKey rsaKey = (RSAKey) JWK.parseFromPEMEncodedObjects(pemEncodedRSAPrivateKey); + signedJWT.sign(new RSASSASigner(rsaKey.toRSAPrivateKey())); + + //5. Finally the JWT access token + String accessToken = signedJWT.serialize(); + + return Json.createObjectBuilder() + .add("token_type", "Bearer") + .add("access_token", accessToken) + .add("expires_in", expiresInMin * 60) + .add("scope", authorizationCode.getApprovedScopes()) + .build(); + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationGrantTypeHandler.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationGrantTypeHandler.java new file mode 100644 index 0000000000..a5afe293ef --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/handler/AuthorizationGrantTypeHandler.java @@ -0,0 +1,8 @@ +package com.baeldung.oauth2.authorization.server.handler; + +import javax.json.JsonObject; +import javax.ws.rs.core.MultivaluedMap; + +public interface AuthorizationGrantTypeHandler { + JsonObject createAccessToken(String clientId, MultivaluedMap params) throws Exception; +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AppDataRepository.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AppDataRepository.java new file mode 100644 index 0000000000..6b827d6a3d --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AppDataRepository.java @@ -0,0 +1,27 @@ +package com.baeldung.oauth2.authorization.server.model; + +import javax.enterprise.context.ApplicationScoped; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.transaction.Transactional; + +@ApplicationScoped +public class AppDataRepository { + + @PersistenceContext + private EntityManager entityManager; + + public Client getClient(String clientId) { + return entityManager.find(Client.class, clientId); + } + + public User getUser(String userId) { + return entityManager.find(User.class, userId); + } + + @Transactional + public AuthorizationCode save(AuthorizationCode authorizationCode) { + entityManager.persist(authorizationCode); + return authorizationCode; + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AuthorizationCode.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AuthorizationCode.java new file mode 100644 index 0000000000..a2ec088eb9 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/AuthorizationCode.java @@ -0,0 +1,73 @@ +package com.baeldung.oauth2.authorization.server.model; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Table(name = "authorization_code") +public class AuthorizationCode { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "code") + private String code; + @Column(name = "client_id") + private String clientId; + @Column(name = "user_id") + private String userId; + @Column(name = "approved_scopes") + private String approvedScopes; + + @Column(name = "redirect_uri") + private String redirectUri; + + @Column(name = "expiration_date") + private LocalDateTime expirationDate; + + public String getUserId() { + return userId; + } + + public void setUserId(String username) { + this.userId = username; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getApprovedScopes() { + return approvedScopes; + } + + public void setApprovedScopes(String approvedScopes) { + this.approvedScopes = approvedScopes; + } + + public String getRedirectUri() { + return redirectUri; + } + + public void setRedirectUri(String redirectUri) { + this.redirectUri = redirectUri; + } + + public LocalDateTime getExpirationDate() { + return expirationDate; + } + + public void setExpirationDate(LocalDateTime expirationDate) { + this.expirationDate = expirationDate; + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/Client.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/Client.java new file mode 100644 index 0000000000..9b5ad2f904 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/Client.java @@ -0,0 +1,62 @@ +package com.baeldung.oauth2.authorization.server.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "clients") +public class Client { + @Id + @Column(name = "client_id") + private String clientId; + @Column(name = "client_secret") + private String clientSecret; + @Column(name = "redirect_uri") + private String redirectUri; + @Column(name = "scope") + private String scope; + @Column(name = "authorized_grant_types") + private String authorizedGrantTypes; + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public String getRedirectUri() { + return redirectUri; + } + + public void setRedirectUri(String redirectUri) { + this.redirectUri = redirectUri; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getAuthorizedGrantTypes() { + return authorizedGrantTypes; + } + + public void setAuthorizedGrantTypes(String authorizedGrantTypes) { + this.authorizedGrantTypes = authorizedGrantTypes; + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/User.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/User.java new file mode 100644 index 0000000000..b3821715f4 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/model/User.java @@ -0,0 +1,58 @@ +package com.baeldung.oauth2.authorization.server.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.security.Principal; + +@Entity +@Table(name = "users") +public class User implements Principal { + @Id + @Column(name = "user_id") + private String userId; + @Column(name = "password") + private String password; + @Column(name = "roles") + private String roles; + @Column(name = "scopes") + private String scopes; + + public String getUserId() { + return userId; + } + + public void setUserId(String username) { + this.userId = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getRoles() { + return roles; + } + + public void setRoles(String roles) { + this.roles = roles; + } + + public String getScopes() { + return scopes; + } + + public void setScopes(String scopes) { + this.scopes = scopes; + } + + @Override + public String getName() { + return getUserId(); + } +} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/security/UserIdentityStore.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/security/UserIdentityStore.java new file mode 100644 index 0000000000..a32ab32cd4 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/security/UserIdentityStore.java @@ -0,0 +1,37 @@ +package com.baeldung.oauth2.authorization.server.security; + +import com.baeldung.oauth2.authorization.server.model.AppDataRepository; +import com.baeldung.oauth2.authorization.server.model.User; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.security.enterprise.credential.Credential; +import javax.security.enterprise.credential.UsernamePasswordCredential; +import javax.security.enterprise.identitystore.CredentialValidationResult; +import javax.security.enterprise.identitystore.IdentityStore; +import javax.transaction.Transactional; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; + +import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT; + +@ApplicationScoped +@Transactional +public class UserIdentityStore implements IdentityStore { + + @Inject + private AppDataRepository appDataRepository; + + @Override + public CredentialValidationResult validate(Credential credential) { + UsernamePasswordCredential usernamePasswordCredential = (UsernamePasswordCredential) credential; + String userId = usernamePasswordCredential.getCaller(); + User user = appDataRepository.getUser(userId); + Objects.requireNonNull(user, "User should be not null"); + if (usernamePasswordCredential.getPasswordAsString().equals(user.getPassword())) { + return new CredentialValidationResult(userId, new HashSet<>(Arrays.asList(user.getRoles().split(",")))); + } + return INVALID_RESULT; + } +} \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/AuthorizationEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/AuthorizationEndpoint.java new file mode 100644 index 0000000000..84b9a89c54 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/AuthorizationEndpoint.java @@ -0,0 +1,209 @@ +//package com.baeldung.security.oauth2.server.web; +// +//import AuthorizationCode; +//import Client; +//import User; +//import com.baeldung.security.oauth2.server.service.AuthCodeService; +// +//import javax.ejb.EJB; +//import javax.enterprise.context.RequestScoped; +//import javax.inject.Inject; +//import javax.persistence.EntityManager; +//import javax.persistence.PersistenceContext; +//import javax.security.enterprise.SecurityContext; +//import javax.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition; +//import javax.security.enterprise.authentication.mechanism.http.LoginToContinue; +//import javax.servlet.ServletException; +//import javax.servlet.annotation.HttpConstraint; +//import javax.servlet.annotation.ServletSecurity; +//import javax.servlet.annotation.WebServlet; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.io.IOException; +//import java.security.Principal; +//import java.util.*; +// +///** +// * 1. GET http://localhost:8080/app/ (302) +// * 2. GET http://localhost:8080/uaa/authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 (302) +// * 3. GET http://localhost:8080/uaa/login (200) with initial request as hidden input +// * 4. POST http://localhost:8080/uaa/login (username, password, initial client request) (302) +// * 5. GET http://localhost:8080/uaa/authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 (200) +// * 7. POST http://localhost:8080/uaa/authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 (302) +// * 8. GET http://localhost:8080/app/?code=rkWijq06mL&state=A123 (200) +// */ +///* +// +//Query Params: +// client_id: app +// redirect_uri: http://localhost:8080/app/ +// response_type: code +// state: A123 +// +// ==> GET user login WITH client request as hidden input: +// +// +// ==> After user login ==> Initial client request +// ==> gen code +// == redirect to redirect uri + params code & state : 302, location : http://localhost:8080/app/?code=w6A0YQFzzg&state=A123 +//*/ +// +////authorize?client_id=app&redirect_uri=http://localhost:8080/app/&response_type=code&state=A123 +////http://localhost:9080/authorize?response_type=code&client_id=client_id_1&redirect_uri=http://localhost:9080/app&state=A123 +// +////@RequestScoped +//@FormAuthenticationMechanismDefinition( +// loginToContinue = @LoginToContinue( +// loginPage = "/login-servlet", +// errorPage = "/login-error-servlet" +// ) +//) +//@WebServlet({"/authorize"}) +//@ServletSecurity(@HttpConstraint(rolesAllowed = "user")) +////@Stateless +//@RequestScoped +//public class AuthorizationEndpoint extends HttpServlet { +// +// private static final List authorizedResponseTypes = Arrays.asList("code", "token"); +// +// @Inject +// private SecurityContext securityContext; +// +// @PersistenceContext(name = "jpa-oauth2-pu") +// private EntityManager entityManager; +// +// @EJB +// private AuthCodeService authCodeService; +// +// //HTTP GET IS A MUST, POST IS OPTIONAL +// @Override +// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +// +// String error = ""; +// +// //1. User Authentication +// Principal principal = securityContext.getCallerPrincipal(); +// +// //2. Check for a valid client_id +// String clientId = request.getParameter("client_id"); +// if (clientId == null) { +// request.setAttribute("error", "The client " + clientId + " doesn't exist."); +// } +// request.setAttribute("clientId", clientId); +// Client client = entityManager.find(Client.class, clientId); +// if (client == null) { +// request.setAttribute("error", "The client " + clientId + " doesn't exist."); +// } +// +// //3. check for a valid response_type +// String responseType = request.getParameter("response_type"); +// if (!authorizedResponseTypes.contains(responseType)) { +// error = "invalid_grant :" + responseType + ", response_type params should be one of :" + authorizedResponseTypes; +// request.setAttribute("error", error); +// request.getRequestDispatcher("/error.jsp") +// .forward(request, response); +// } +// +// //4. Optional redirect_uri, if provided should match +// String redirectUri = request.getParameter("redirect_uri"); +// checkRedirectUri(client, redirectUri); +// +// //save params +// String currentUri = request.getRequestURI(); +// request.setAttribute("post_redirect_uri", currentUri); +// +// String state = request.getParameter("state"); +// Map requestMap = new HashMap<>(); +// requestMap.put("response_type", responseType); +// requestMap.put("client_id", clientId); +// requestMap.put("redirect_uri", redirectUri); +// requestMap.put("state", state); +// request.setAttribute("requestMap", requestMap); +// +// //5.scope: Optional +// String requestedScope = request.getParameter("scope"); +// if (requestedScope.isEmpty()) { +// requestedScope = client.getScope(); +// } +// //requestedScope should be a subset of the client scope: clientScopes.containsAll(requestedScopes) +// //checkRequestedScope(requestedScope, client.getScope()); +// +// //sub set of user scope +// //allowed scope by the user +// +// User user = entityManager.find(User.class, principal.getName()); +// request.setAttribute("scopes", requestedScope); +// +// +// forward("/authorize.jsp", request, response); +// } +// +// @Override +// protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +// String clientId = request.getParameter("client_id"); +// +// String responseType = request.getParameter("response_type"); +// if (!authorizedResponseTypes.contains(responseType)) { +// String error = "invalid_grant :" + responseType + ", response_type params should be one of :" + authorizedResponseTypes; +// request.setAttribute("error", error); +// forward("/error.jsp", request, response); +// } +// +// Client client = entityManager.find(Client.class, clientId); +// Objects.requireNonNull(client); +// +// String userId = securityContext.getCallerPrincipal().getName(); +// AuthorizationCode authorizationCode = new AuthorizationCode(); +// authorizationCode.setClientId(clientId); +// authorizationCode.setUserId(userId); +// String redirectUri = request.getParameter("redirect_uri"); +// authorizationCode.setRedirectUri(redirectUri); +// +// redirectUri = checkRedirectUri(client, redirectUri); +// +// String[] scope = request.getParameterValues("scope"); +// if (scope == null) { +// request.setAttribute("error", "User doesn't approved any scope"); +// forward("/error.jsp", request, response); +// } +// +// String approvedScopes = String.join(" ", scope); +// authorizationCode.setApprovedScopes(approvedScopes); +// +// //entityManager.persist(authorizationCode); +// authCodeService.save(authorizationCode); +// String code = authorizationCode.getCode(); +// +// StringBuilder sb = new StringBuilder(redirectUri); +// sb.append("?code=").append(code); +// +// //If the client send a state, Send it back +// String state = request.getParameter("state"); +// if (state != null) { +// sb.append("&state=").append(state); +// } +// response.sendRedirect(sb.toString()); +// } +// +// private String checkRedirectUri(Client client, String redirectUri) { +// //redirect uri +// if (redirectUri == null) { +// //erreur: param redirect_uri && client redirect_uri don't match. +// redirectUri = client.getRedirectUri(); +// if (redirectUri == null) { +// throw new IllegalStateException("redirectUri shloud be not null, unless a registred client have a redirect_uri."); +// } +// } else if (!redirectUri.equals(client.getRedirectUri())) { +// throw new IllegalStateException("request redirectUri and client registred redirect_uri should match."); +// } +// return redirectUri; +// } +// +// private void forward(String path, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +// request.getRequestDispatcher(path) +// .forward(request, response); +// } +//} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/TokenEndpoint.java b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/TokenEndpoint.java new file mode 100644 index 0000000000..73085a68d1 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/java/com/baeldung/oauth2/authorization/server/web/TokenEndpoint.java @@ -0,0 +1,70 @@ +//package com.baeldung.security.oauth2.server.web; +// +//import AuthorizationGrantTypeHandler; +//import TokenResponse; +//import com.baeldung.security.oauth2.server.security.Authenticated; +//import com.nimbusds.jose.JOSEException; +// +//import javax.enterprise.inject.Instance; +//import javax.enterprise.inject.literal.NamedLiteral; +//import javax.inject.Inject; +//import javax.security.enterprise.SecurityContext; +//import javax.ws.rs.Consumes; +//import javax.ws.rs.POST; +//import javax.ws.rs.Path; +//import javax.ws.rs.Produces; +//import javax.ws.rs.core.MediaType; +//import javax.ws.rs.core.MultivaluedMap; +//import javax.ws.rs.core.Response; +//import java.security.Principal; +//import java.util.Arrays; +//import java.util.List; +//import java.util.Objects; +// +///** +// * { +// * "access_token" : "acb6803a48114d9fb4761e403c17f812", +// * "token_type" : "bearer", +// * "id_token" : "eyJhbGciOiJIUzI1NiIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAvdWFhL3Rva2VuX2tleXMiLCJraWQiOiJsZWdhY3ktdG9rZW4ta2V5IiwidHlwIjoiSldUIn0.eyJzdWIiOiIwNzYzZTM2MS02ODUwLTQ3N2ItYjk1Ny1iMmExZjU3MjczMTQiLCJhdWQiOlsibG9naW4iXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3VhYS9vYXV0aC90b2tlbiIsImV4cCI6MTU1NzgzMDM4NSwiaWF0IjoxNTU3Nzg3MTg1LCJhenAiOiJsb2dpbiIsInNjb3BlIjpbIm9wZW5pZCJdLCJlbWFpbCI6IndyaHBONUB0ZXN0Lm9yZyIsInppZCI6InVhYSIsIm9yaWdpbiI6InVhYSIsImp0aSI6ImFjYjY4MDNhNDgxMTRkOWZiNDc2MWU0MDNjMTdmODEyIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImNsaWVudF9pZCI6ImxvZ2luIiwiY2lkIjoibG9naW4iLCJncmFudF90eXBlIjoiYXV0aG9yaXphdGlvbl9jb2RlIiwidXNlcl9uYW1lIjoid3JocE41QHRlc3Qub3JnIiwicmV2X3NpZyI6ImI3MjE5ZGYxIiwidXNlcl9pZCI6IjA3NjNlMzYxLTY4NTAtNDc3Yi1iOTU3LWIyYTFmNTcyNzMxNCIsImF1dGhfdGltZSI6MTU1Nzc4NzE4NX0.Fo8wZ_Zq9mwFks3LfXQ1PfJ4ugppjWvioZM6jSqAAQQ", +// * "refresh_token" : "f59dcb5dcbca45f981f16ce519d61486-r", +// * "expires_in" : 43199, +// * "scope" : "openid oauth.approvals", +// * "jti" : "acb6803a48114d9fb4761e403c17f812" +// * } +// */ +//@Path("token") +//public class TokenEndpoint { +// +// List supportedGrantTypes = Arrays.asList("authorization_code", "password", "refresh_token", "client_credentials"); +// +// @Inject +// private SecurityContext securityContext; +// +// @Inject +// Instance authorizationGrantTypeHandlers; +// +// @POST +// @Produces(MediaType.APPLICATION_JSON) +// @Consumes(MediaType.APPLICATION_FORM_URLENCODED) +// @Authenticated +// public Response token(MultivaluedMap params) throws JOSEException { +// //Authenticate client with [basic] http authentication mechanism +// Principal principal = securityContext.getCallerPrincipal(); +// Objects.requireNonNull(principal, "Client not authenticated!"); +// +// //Check grant_type params +// String grantType = params.getFirst("grant_type"); +// Objects.requireNonNull(grantType, "grant_type params is required"); +// //authorization_code, password, refresh, client_credentials +// if (!supportedGrantTypes.contains(grantType)) { +// throw new RuntimeException("grant_type parameter should be one of the following :" + supportedGrantTypes); +// } +// AuthorizationGrantTypeHandler authorizationGrantTypeHandler = authorizationGrantTypeHandlers.select(NamedLiteral.of(grantType)).get(); +// TokenResponse tokenResponse = authorizationGrantTypeHandler.createAccessToken(principal.getName(), params); +// Response response = Response.ok(tokenResponse) +// .header("Cache-Control", "no-store") +// .header("Pragma", "no-cache") +// .build(); +// return response; +// } +//} diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/liberty/config/server.xml b/oauth2-framework-impl/oauth2-authorization-server/src/main/liberty/config/server.xml new file mode 100644 index 0000000000..97d9ec4a28 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/liberty/config/server.xml @@ -0,0 +1,32 @@ + + + + + localConnector-1.0 + cdi-2.0 + jaxrs-2.1 + jpa-2.2 + appSecurity-3.0 + jsp-2.3 + mpConfig-1.3 + + + + + + + + + + + + + + + + + diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/microprofile-config.properties b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 0000000000..d9c68bc111 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,2 @@ +signingkey=/META-INF/private-key.pem +verificationkey=/META-INF/public-key.pem diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/persistence.xml b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..a10ad3c886 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,14 @@ + + + + jdbc/OAuth2_DS + + + + + + \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/private-key.pem b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/private-key.pem new file mode 100644 index 0000000000..6e36cb4d78 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/private-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDYizUyvwY6qMd0 +ZkYPzP9mLTJOSczW8WtAbjhrgxk5LORIjcdv/aB1BAzDEOCX4UC+Rbs9YwaekIvW +7dL/t6xPzsA7+9tMt27TqUxXigWEFQG73w/WbEVzCG09IHqG7Ztjb6aGL+8pfcu+ +SLvOtXWrctHNbr35BYC5yBQaos9bH+nLYbh2Ff+emrpg7Kwoeis6MY6RgZIL/lxt +3beZt1NQhLEvB9t6XoSkyLQKSjT/OC8XOa4OYI4OfOSFqEUEp+8dKe3svZbQUNJf +KKehx78xx0rfwH+iBsFKkHdvt1ZHtINvYedAfGrc5rWnesunzOW7OKMAiIXAJSRA +rn9Iv5/fAgMBAAECggEAYHKwgSfAGIRwQhIDhqoh31qmG2SXjez9fjcZfhloNKUg +EIjFmcX3n+br4D42Kq+zbIwWd6MRobJz9oj6/9bJMsq9qHnnFWZmQHQZgqwBBPFu +UkVqAnE7BZ9tOFqs+EgAe+uQ2hejiHF1PA2dSNZd0L1VYRDAIJgo25aYDb0Sal0c +qaFmK1XzPnSIhgnopKP/TmUfALjeshtGvh6WkiXHTY2VKJlyLEiGd3/1tBZnzwSQ +QiS/2zfXL7lO0SYRA10m1BmtqGi3wSKIXUA6tNulmpXEMnYk4RtsqBClOanzQIm7 +f4Ie59AtUUlDdHzRmhxBaDprgAI/FdCxXkseLzk5sQKBgQDyptOhJ/VQ5tkgffJW +X2QwGIaNdvNCEL4GlgXKAWNkCzT4h+Q/2wFoKhaN2JH2YZwKCRwG/UZh4Hq22fdx +fa/DP8PK3zlX0c9dWQOtmBOe0/nG28kq9iqziP3ILLNuelfaMhxtRkUmR652VCzx +qazZmjoo2MxtA6BMiK3Vx5aikwKBgQDkdLalVveHKTVkrplQYNapQAtAwjlsNnMt +VJh6nLo3eOg1xBNA7JrYqx7sXRQInUGAyNKvgQL/lCQdMkTzyetLjJGsiFSEgeot +RMsDXBrJFYZiErbpQungpaevwAymaGi++nbCzhw1/n3AvVUhRKNknX8Ms0UKlLRZ +TCktCTChBQKBgGA7ZzzHgxPFqaCoMl6s0Cf+4gXigdDWoPYtszgM2uUHSMez5QKq +EWHFJ1Kz7BdBWMfmGvZupeYVR7WStf6NcRJHDJg9dRlt/QYxUjMbV9Sqjqmd6qce +H4s6LiOgDr0mygafzwRLVQs8bGVDNtvUhdd6wcwHRvOI957CqeZZlFT/AoGBAN2P +j79EW6U6wuyVJF0+vZDBauhwNQ6MtCEnZQWs0DCSUuop8d5KWVZ+huwGzTIZiPhk +S2goP4cs3eVu5k5k6oyHlJP2V7l24WzrxdPJVLTl6kFdEwWgfn//SGR7ZglRQxzM +fbcp+1QmL0FonZI5JhmjYR8pEXFUjJ/57AkgW4gdAoGASV3TlaNd+reb2l0kETqp +HrzzMIYkM2faZ8LmpcEO0wz606SK468bnl6SqVBYT2J0bkqCpEmPBtWs/OFCWd6x +93NndSfJk57/7AqNxfVyZWp2sjRzt5vZ4KPlRVvMHIGeJNbIV7RqUr6XGu+u3ZrS +B7SqwKZqdHVSULG9nMK7Iz8= +-----END PRIVATE KEY----- diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/public-key.pem b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/public-key.pem new file mode 100644 index 0000000000..f53ceca446 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/META-INF/public-key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Is1Mr8GOqjHdGZGD8z/ +Zi0yTknM1vFrQG44a4MZOSzkSI3Hb/2gdQQMwxDgl+FAvkW7PWMGnpCL1u3S/7es +T87AO/vbTLdu06lMV4oFhBUBu98P1mxFcwhtPSB6hu2bY2+mhi/vKX3Lvki7zrV1 +q3LRzW69+QWAucgUGqLPWx/py2G4dhX/npq6YOysKHorOjGOkYGSC/5cbd23mbdT +UISxLwfbel6EpMi0Cko0/zgvFzmuDmCODnzkhahFBKfvHSnt7L2W0FDSXyinoce/ +McdK38B/ogbBSpB3b7dWR7SDb2HnQHxq3Oa1p3rLp8zluzijAIiFwCUkQK5/SL+f +3wIDAQAB +-----END PUBLIC KEY----- diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/data.sql b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/data.sql new file mode 100644 index 0000000000..ecda0fa2ad --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/resources/data.sql @@ -0,0 +1,3 @@ +INSERT INTO `users` (`user_id`, `password`, `roles`, `scopes`) VALUES ('appuser', 'appusersecret', 'USER', 'resource.read resource.write'); + +INSERT INTO `clients` (`client_id`, `client_secret`, `redirect_uri`,`scope`,`authorized_grant_types`) VALUES ('webappclient', 'webappclientsecret', 'http://localhost:9180/callback', 'resource.read resource.write', 'authorization_code refresh_token'); \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/WEB-INF/beans.xml b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..29595ff490 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp new file mode 100644 index 0000000000..1004b5b8b7 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/authorize.jsp @@ -0,0 +1,54 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + Authorization + + + + +
+

Want to Authorize scopes for client : ${client.clientId} ?

+
+ +
+ + + + + + + + + +
Scopes : + + ${scope}
+
+
+ + +
+
+ +
+ + + diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/error.jsp b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/error.jsp new file mode 100644 index 0000000000..edb0bf28b7 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/error.jsp @@ -0,0 +1,25 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> + + + + + + Error + + + + + + +
+

${error}

+
+ + + \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/login-error.jsp b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/login-error.jsp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/login.jsp b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/login.jsp new file mode 100644 index 0000000000..1d2dd93fd0 --- /dev/null +++ b/oauth2-framework-impl/oauth2-authorization-server/src/main/webapp/login.jsp @@ -0,0 +1,49 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> + + + + + Login Form + + + + +
+

Login Form

+
+
+ + + + + + + + + + + + + +
Username
Password
+
+ +
+ + + \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-client/pom.xml b/oauth2-framework-impl/oauth2-client/pom.xml new file mode 100644 index 0000000000..e46a44268e --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + oauth2-client + war + + + com.baeldung.oauth2 + oauth2-framework-impl + 1.0-SNAPSHOT + + + + 9180 + 9543 + + + + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + + + + diff --git a/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/AuthorizationCodeServlet.java b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/AuthorizationCodeServlet.java new file mode 100644 index 0000000000..a5fdaf07f2 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/AuthorizationCodeServlet.java @@ -0,0 +1,39 @@ +package com.baeldung.oauth2.client; + +import org.eclipse.microprofile.config.Config; + +import javax.inject.Inject; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.UUID; + +@WebServlet(urlPatterns = "/authorize") +public class AuthorizationCodeServlet extends HttpServlet { + + @Inject + private Config config; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + //... + request.getSession().removeAttribute("tokenResponse"); + String state = UUID.randomUUID().toString(); + request.getSession().setAttribute("CLIENT_LOCAL_STATE", state); + + String authorizationUri = config.getValue("provider.authorizationUri", String.class); + String clientId = config.getValue("client.clientId", String.class); + String redirectUri = config.getValue("client.redirectUri", String.class); + String scope = config.getValue("client.scope", String.class); + + String authorizationLocation = authorizationUri + "?response_type=code" + + "&client_id=" + clientId + + "&redirect_uri=" + redirectUri + + "&scope=" + scope + + "&state=" + state; + response.sendRedirect(authorizationLocation); + } +} diff --git a/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java new file mode 100644 index 0000000000..87aa8bc668 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/CallbackServlet.java @@ -0,0 +1,76 @@ +package com.baeldung.oauth2.client; + +import org.eclipse.microprofile.config.Config; + +import javax.inject.Inject; +import javax.json.JsonObject; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.Base64; + +@WebServlet(urlPatterns = "/callback") +public class CallbackServlet extends HttpServlet { + + @Inject + private Config config; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + //Error: + String error = request.getParameter("error"); + if (error != null) { + request.setAttribute("error", error); + dispatch("/", request, response); + return; + } + String localState = (String) request.getSession().getAttribute("CLIENT_LOCAL_STATE"); + if (!localState.equals(request.getParameter("state"))) { + request.setAttribute("error", "The state attribute doesn't match !!"); + dispatch("/", request, response); + return; + } + + String code = request.getParameter("code"); + + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(config.getValue("provider.tokenUri", String.class)); + + Form form = new Form(); + form.param("grant_type", "authorization_code"); + form.param("code", code); + form.param("redirect_uri", config.getValue("client.redirectUri", String.class)); + + JsonObject tokenResponse = target.request(MediaType.APPLICATION_JSON_TYPE) + .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeaderValue()) + .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), JsonObject.class); + + request.getSession().setAttribute("tokenResponse", tokenResponse); + dispatch("/", request, response); + } + + private void dispatch(String location, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + RequestDispatcher requestDispatcher = request.getRequestDispatcher(location); + requestDispatcher.forward(request, response); + } + + private String getAuthorizationHeaderValue() { + String clientId = config.getValue("client.clientId", String.class); + String clientSecret = config.getValue("client.clientSecret", String.class); + String token = clientId + ":" + clientSecret; + String encodedString = Base64.getEncoder().encodeToString(token.getBytes()); + return "Basic " + encodedString; + } +} diff --git a/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/DownstreamCallServlet.java b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/DownstreamCallServlet.java new file mode 100644 index 0000000000..bbe850917b --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/java/com/baeldung/oauth2/client/DownstreamCallServlet.java @@ -0,0 +1,49 @@ +package com.baeldung.oauth2.client; + +import org.eclipse.microprofile.config.Config; + +import javax.inject.Inject; +import javax.json.JsonObject; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.client.*; +import java.io.IOException; +import java.io.PrintWriter; + +@WebServlet(urlPatterns = "/downstream") +public class DownstreamCallServlet extends HttpServlet { + + @Inject + private Config config; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { + resp.setContentType("text/html;charset=UTF-8"); + String action = request.getParameter("action"); + Client client = ClientBuilder.newClient(); + WebTarget webTarget = client.target(config.getValue("resourceServerUri", String.class)); + WebTarget resourceWebTarget; + String response = null; + JsonObject tokenResponse = (JsonObject) request.getSession().getAttribute("tokenResponse"); + if ("read".equals(action)) { + resourceWebTarget = webTarget.path("resource/read"); + Invocation.Builder invocationBuilder = resourceWebTarget.request(); + response = invocationBuilder + .header("authorization", tokenResponse.getString("access_token")) + .get(String.class); + } else if ("write".equals(action)) { + resourceWebTarget = webTarget.path("resource/write"); + Invocation.Builder invocationBuilder = resourceWebTarget.request(); + response = invocationBuilder + .header("authorization", tokenResponse.getString("access_token")) + .post(Entity.text("body string"), String.class); + } + PrintWriter out = resp.getWriter(); + out.println(response); + out.flush(); + out.close(); + } +} diff --git a/oauth2-framework-impl/oauth2-client/src/main/liberty/config/server.xml b/oauth2-framework-impl/oauth2-client/src/main/liberty/config/server.xml new file mode 100644 index 0000000000..26dc730361 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/liberty/config/server.xml @@ -0,0 +1,19 @@ + + + + + localConnector-1.0 + cdi-2.0 + jsp-2.3 + mpConfig-1.3 + jaxrsClient-2.1 + jsonp-1.1 + + + + + + + + + diff --git a/oauth2-framework-impl/oauth2-client/src/main/resources/META-INF/microprofile-config.properties b/oauth2-framework-impl/oauth2-client/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 0000000000..d66f4f6a74 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,12 @@ +#Client registration +client.clientId=webappclient +client.clientSecret=webappclientsecret +client.redirectUri=http://localhost:9180/callback +client.scope=resource.read resource.write + +#Provider +provider.authorizationUri=http://127.0.0.1:9080/authorize +provider.tokenUri=http://127.0.0.1:9080/token + +#Resource Server +resourceServerUri=http://localhost:9280/api \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/beans.xml b/oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..29595ff490 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + diff --git a/oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/web.xml b/oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..0203894c1b --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,5 @@ + + + index.jsp + + \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp b/oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp new file mode 100644 index 0000000000..23fec70f33 --- /dev/null +++ b/oauth2-framework-impl/oauth2-client/src/main/webapp/index.jsp @@ -0,0 +1,97 @@ +<%@ page import="org.eclipse.microprofile.config.Config" %> +<%@ page import="org.eclipse.microprofile.config.ConfigProvider" %> + + + + + + OAuth2 Client + + + + + +<% + Config config1 = ConfigProvider.getConfig(); +%> + +
"> + Error : ${error} +
+ +
+

OAuth2 Authorization Server

+
+

Client Registration :

+
    +
  • client_id: <%=config1.getValue("client.clientId", String.class)%> +
  • +
  • client_secret: <%=config1.getValue("client.clientSecret", String.class)%> +
  • +
  • redirect_uri: <%=config1.getValue("client.redirectUri", String.class)%> +
  • +
  • scope: <%=config1.getValue("client.scope", String.class)%> +
  • +
+

Authorization Server :

+
    +
  • authorization_uri: <%=config1.getValue("provider.authorizationUri", String.class)%> +
  • +
  • token_uri: <%=config1.getValue("provider.tokenUri", String.class)%> +
  • +
+
+
+

OAuth2 Client

+
+

Token Request :

+ + +

Token Response:

+
    +
  • access_token: ${tokenResponse.getString("access_token")}
  • +
  • scope: ${tokenResponse.getString("scope")}
  • +
  • Expires in (s): ${tokenResponse.getInt("expires_in")}
  • +
+
+
+

OAuth2 Resource Server Call

+
+ + +
+ + + \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-resource-server/pom.xml b/oauth2-framework-impl/oauth2-resource-server/pom.xml new file mode 100644 index 0000000000..9b58c33472 --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + oauth2-resource-server + war + + + com.baeldung.oauth2 + oauth2-framework-impl + 1.0-SNAPSHOT + + + + 9280 + 8643 + http://localhost:9080 + http://localhost:9280 + + + + + org.eclipse.microprofile.jwt + microprofile-jwt-auth-api + 1.1 + provided + + + + + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + + + + + diff --git a/oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/OAuth2ResourceServerApplication.java b/oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/OAuth2ResourceServerApplication.java new file mode 100644 index 0000000000..835e80a416 --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/OAuth2ResourceServerApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.oauth2.resource.server; + +import org.eclipse.microprofile.auth.LoginConfig; + +import javax.annotation.security.DeclareRoles; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +@ApplicationPath("/api") +@DeclareRoles({"resource.read", "resource.write"}) +@LoginConfig(authMethod = "MP-JWT") +public class OAuth2ResourceServerApplication extends Application { +} diff --git a/oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/secure/ProtectedResource.java b/oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/secure/ProtectedResource.java new file mode 100644 index 0000000000..300de83c6d --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/src/main/java/com/baeldung/oauth2/resource/server/secure/ProtectedResource.java @@ -0,0 +1,38 @@ +package com.baeldung.oauth2.resource.server.secure; + +import org.eclipse.microprofile.jwt.JsonWebToken; + +import javax.annotation.security.RolesAllowed; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import java.util.UUID; + +@Path("/resource") +@RequestScoped +public class ProtectedResource { + + @Inject + private JsonWebToken principal; + + @GET + @RolesAllowed("resource.read") + @Path("/read") + public Response read() { + //DoStaff + return Response.ok("Hello, " + principal.getName()).build(); + } + + @POST + @RolesAllowed("resource.write") + @Path("/write") + public Response write() { + //DoStaff + return Response.ok("Hello, " + principal.getName()) + .header("location", UUID.randomUUID().toString()) + .build(); + } +} diff --git a/oauth2-framework-impl/oauth2-resource-server/src/main/liberty/config/server.xml b/oauth2-framework-impl/oauth2-resource-server/src/main/liberty/config/server.xml new file mode 100644 index 0000000000..c54d698359 --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/src/main/liberty/config/server.xml @@ -0,0 +1,20 @@ + + + + + localConnector-1.0 + cdi-2.0 + jaxrs-2.1 + jsonp-1.1 + mpConfig-1.3 + mpJwt-1.1 + + + + + + + + + + diff --git a/oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/microprofile-config.properties b/oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 0000000000..be6919ec50 --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,2 @@ +mp.jwt.verify.publickey.location=/META-INF/public-key.pem +mp.jwt.verify.issuer=http://localhost:9080 \ No newline at end of file diff --git a/oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/public-key.pem b/oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/public-key.pem new file mode 100644 index 0000000000..f53ceca446 --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/src/main/resources/META-INF/public-key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Is1Mr8GOqjHdGZGD8z/ +Zi0yTknM1vFrQG44a4MZOSzkSI3Hb/2gdQQMwxDgl+FAvkW7PWMGnpCL1u3S/7es +T87AO/vbTLdu06lMV4oFhBUBu98P1mxFcwhtPSB6hu2bY2+mhi/vKX3Lvki7zrV1 +q3LRzW69+QWAucgUGqLPWx/py2G4dhX/npq6YOysKHorOjGOkYGSC/5cbd23mbdT +UISxLwfbel6EpMi0Cko0/zgvFzmuDmCODnzkhahFBKfvHSnt7L2W0FDSXyinoce/ +McdK38B/ogbBSpB3b7dWR7SDb2HnQHxq3Oa1p3rLp8zluzijAIiFwCUkQK5/SL+f +3wIDAQAB +-----END PUBLIC KEY----- diff --git a/oauth2-framework-impl/oauth2-resource-server/src/main/webapp/WEB-INF/beans.xml b/oauth2-framework-impl/oauth2-resource-server/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..2777559c20 --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + diff --git a/oauth2-framework-impl/oauth2-resource-server/src/main/webapp/index.html b/oauth2-framework-impl/oauth2-resource-server/src/main/webapp/index.html new file mode 100644 index 0000000000..7ea29c1097 --- /dev/null +++ b/oauth2-framework-impl/oauth2-resource-server/src/main/webapp/index.html @@ -0,0 +1,37 @@ + + + + + Eclipse MicroProfile demo + + + +

MicroProfile

+ +Hello JAX-RS endpoint
+ + +

Config

+Injected config values
+Config values by lookup
+ + + + + + + + + +

JWT Auth

+Look at readme.md on how to test protected endpoint. + + + + + + + + + + \ No newline at end of file diff --git a/oauth2-framework-impl/pom.xml b/oauth2-framework-impl/pom.xml new file mode 100644 index 0000000000..281103660b --- /dev/null +++ b/oauth2-framework-impl/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + com.baeldung.oauth2 + oauth2-framework-impl + 1.0-SNAPSHOT + pom + + + 1.8 + 1.8 + false + RELEASE + 2.6.4 + + + + + javax + javaee-web-api + 8.0 + provided + + + org.eclipse.microprofile.config + microprofile-config-api + 1.3 + provided + + + + + ${project.artifactId} + + + ${basedir}/src/main/resources + + **/*.* + + + + true + ${basedir}/src/main/liberty + + **/*.* + + + + + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + ${openliberty.maven.version} + + + package-server + package + + create-server + install-apps + + + target/wlp-package + + + + + + io.openliberty + openliberty-webProfile8 + ${openliberty.version} + zip + + target/classes/config/server.xml + ${project.build.directory}/${project.build.finalName}.war + project + ${project.basedir}/src/main/liberty/server + apps + true + + + + + + + oauth2-authorization-server + oauth2-resource-server + oauth2-client + + From 1ba4b23099c33aef663ce30b0ea1b7ca4ba1667f Mon Sep 17 00:00:00 2001 From: Johnathan Gilday Date: Sun, 30 Jun 2019 21:45:57 -0400 Subject: [PATCH 15/74] BAEL-2121 XStream RCE --- xstream/pom.xml | 5 +- .../src/main/java/com/baeldung/rce/App.java | 92 +++++++++++++++++++ .../main/java/com/baeldung/rce/Person.java | 43 +++++++++ .../java/com/baeldung/rce/AppUnitTest.java | 65 +++++++++++++ .../rce/AttackExploitedException.java | 7 ++ .../rce/AttackExploitedExceptionThrower.java | 13 +++ .../baeldung/rce/XStreamBasicsUnitTest.java | 82 +++++++++++++++++ xstream/src/test/resources/attack.xml | 12 +++ .../src/test/resources/calculator-attack.xml | 16 ++++ 9 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 xstream/src/main/java/com/baeldung/rce/App.java create mode 100644 xstream/src/main/java/com/baeldung/rce/Person.java create mode 100644 xstream/src/test/java/com/baeldung/rce/AppUnitTest.java create mode 100644 xstream/src/test/java/com/baeldung/rce/AttackExploitedException.java create mode 100644 xstream/src/test/java/com/baeldung/rce/AttackExploitedExceptionThrower.java create mode 100644 xstream/src/test/java/com/baeldung/rce/XStreamBasicsUnitTest.java create mode 100644 xstream/src/test/resources/attack.xml create mode 100644 xstream/src/test/resources/calculator-attack.xml diff --git a/xstream/pom.xml b/xstream/pom.xml index f75e10fc7d..b98e258599 100644 --- a/xstream/pom.xml +++ b/xstream/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../pom.xml @@ -28,8 +29,8 @@ - 1.4.9 + 1.4.10 1.3.8 - \ No newline at end of file + diff --git a/xstream/src/main/java/com/baeldung/rce/App.java b/xstream/src/main/java/com/baeldung/rce/App.java new file mode 100644 index 0000000000..3720c7fa93 --- /dev/null +++ b/xstream/src/main/java/com/baeldung/rce/App.java @@ -0,0 +1,92 @@ +package com.baeldung.rce; + +import com.sun.net.httpserver.HttpServer; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.security.NoTypePermission; +import com.thoughtworks.xstream.security.NullPermission; +import com.thoughtworks.xstream.security.PrimitiveTypePermission; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.HashSet; +import java.util.Set; + +/** + * Web application which is intentionally vulnerable to an XStream remote code + * exploitation (RCE). + * + *

+ * This test application is meant to maintain a set of {@link Person} models. It + * exposes a "/persons" endpoint which supports the following operations: + * + *

    + *
  1. {@code POST} XML for adding a new {@link Person} to the set + *
  2. {@code GET} for retrieving the set of {@link Person} models as XML + *
+ * + * The {@code POST} handler is vulnerable to an RCE exploit. + */ +public final class App { + + public static App createHardened(int port) { + final XStream xstream = new XStream(); + xstream.addPermission(NoTypePermission.NONE); + xstream.addPermission(NullPermission.NULL); + xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); + xstream.allowTypes(new Class[] { Person.class }); + return new App(port, xstream); + } + + public static App createVulnerable(int port) { + return new App(port, new XStream()); + } + + private final int port; + private final Set persons; + private final XStream xstream; + private HttpServer server; + + private App(int port, XStream xstream) { + this.port = port; + persons = new HashSet<>(); + // this app is vulnerable because XStream security is not configured + this.xstream = xstream; + this.xstream.alias("person", Person.class); + } + + void start() throws IOException { + server = HttpServer.create(new InetSocketAddress("localhost", port), 0); + server.createContext("/persons", exchange -> { + switch (exchange.getRequestMethod()) { + case "POST": + final Person person = (Person) xstream.fromXML(exchange.getRequestBody()); + persons.add(person); + exchange.sendResponseHeaders(201, 0); + exchange.close(); + break; + case "GET": + exchange.sendResponseHeaders(200, 0); + xstream.toXML(persons, exchange.getResponseBody()); + exchange.close(); + break; + default: + exchange.sendResponseHeaders(405, 0); + exchange.close(); + } + }); + server.start(); + } + + void stop() { + if (server != null) { + server.stop(0); + } + } + + int port() { + if (server == null) + throw new IllegalStateException("Server not started"); + return server.getAddress() + .getPort(); + } +} diff --git a/xstream/src/main/java/com/baeldung/rce/Person.java b/xstream/src/main/java/com/baeldung/rce/Person.java new file mode 100644 index 0000000000..336c47798b --- /dev/null +++ b/xstream/src/main/java/com/baeldung/rce/Person.java @@ -0,0 +1,43 @@ +package com.baeldung.rce; + +import java.util.Objects; + +/** Person model */ +public final class Person { + + private String first; + private String last; + + public String getFirst() { + return first; + } + + public void setFirst(String first) { + this.first = first; + } + + public String getLast() { + return last; + } + + public void setLast(String last) { + this.last = last; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Person)) { + return false; + } + Person person = (Person) o; + return Objects.equals(first, person.first) && Objects.equals(last, person.last); + } + + @Override + public int hashCode() { + return Objects.hash(first, last); + } +} diff --git a/xstream/src/test/java/com/baeldung/rce/AppUnitTest.java b/xstream/src/test/java/com/baeldung/rce/AppUnitTest.java new file mode 100644 index 0000000000..3b541ae099 --- /dev/null +++ b/xstream/src/test/java/com/baeldung/rce/AppUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.rce; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.SocketException; +import java.net.URL; + +import static org.junit.Assert.assertTrue; + +/** + * Unit test which demonstrates a remote code exploit against the {@link App} + * server. Sends an XML request containing an attack payload to the {@code POST} + * endpoint. + */ +public final class AppUnitTest { + + private App app; + + /** start a new web server */ + @Before + public void before() throws IOException { + app = App.createVulnerable(0); + app.start(); + } + + /** stop the web server */ + @After + public void after() { + if (app != null) + app.stop(); + } + + /** + * Test passes when an {@link IOException} is thrown because this indicates that + * the attacker caused the application to fail in some way. This does not + * actually confirm that the exploit took place, because the RCE is a + * side-effect that is difficult to observe. + */ + @Test(expected = SocketException.class) + public void givenAppIsVulneable_whenExecuteRemoteCodeWhichThrowsException_thenThrowsException() throws IOException { + // POST the attack.xml to the application's /persons endpoint + final URL url = new URL("http://localhost:" + app.port() + "/persons"); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + connection.setUseCaches(false); + connection.setRequestProperty("Content-Type", "application/xml"); + connection.connect(); + try (OutputStream os = connection.getOutputStream(); InputStream is = AppUnitTest.class.getResourceAsStream("/attack.xml")) { + byte[] buffer = new byte[1024]; + while (is.read(buffer) > 0) { + os.write(buffer); + } + } + final int rc = connection.getResponseCode(); + connection.disconnect(); + assertTrue(rc >= 400); + } +} diff --git a/xstream/src/test/java/com/baeldung/rce/AttackExploitedException.java b/xstream/src/test/java/com/baeldung/rce/AttackExploitedException.java new file mode 100644 index 0000000000..16c906abfc --- /dev/null +++ b/xstream/src/test/java/com/baeldung/rce/AttackExploitedException.java @@ -0,0 +1,7 @@ +package com.baeldung.rce; + +/** + * Indicates a successful remote code execution attack has taken place. + */ +final class AttackExploitedException extends RuntimeException { +} diff --git a/xstream/src/test/java/com/baeldung/rce/AttackExploitedExceptionThrower.java b/xstream/src/test/java/com/baeldung/rce/AttackExploitedExceptionThrower.java new file mode 100644 index 0000000000..16ed143f7a --- /dev/null +++ b/xstream/src/test/java/com/baeldung/rce/AttackExploitedExceptionThrower.java @@ -0,0 +1,13 @@ +package com.baeldung.rce; + +/** + * Class which contains an action to throw {@link AttackExploitedException}. + * This helper is used by {@link AppTest} to determine when the remote code + * exploit has taken place. + */ +final class AttackExploitedExceptionThrower { + + public void throwAttackExploitedException() { + throw new AttackExploitedException(); + } +} diff --git a/xstream/src/test/java/com/baeldung/rce/XStreamBasicsUnitTest.java b/xstream/src/test/java/com/baeldung/rce/XStreamBasicsUnitTest.java new file mode 100644 index 0000000000..d762813b22 --- /dev/null +++ b/xstream/src/test/java/com/baeldung/rce/XStreamBasicsUnitTest.java @@ -0,0 +1,82 @@ +package com.baeldung.rce; + +import com.thoughtworks.xstream.XStream; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Collections; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +/** + * Demonstrates XStream basics + */ +public final class XStreamBasicsUnitTest { + + private XStream xstream; + + @Before + public void before() { + xstream = new XStream(); + xstream.alias("person", Person.class); + } + + @Test + public void whenWritePerson_thenWritesExpectedXml() { + Person person = new Person(); + person.setFirst("John"); + person.setLast("Smith"); + + String xml = xstream.toXML(person); + + // @formatter:off + String expected = "" + + "\n" + + " John\n" + + " Smith\n" + + ""; + // @formatter:on + assertEquals(expected, xml); + + } + + @Test + public void whenReadXmlAsPerson_thenReturnsNewPerson() { + // @formatter:off + String xml = "" + + "" + + " John" + + " Smith" + + ""; + // @formatter:on + + Person person = (Person) xstream.fromXML(xml); + + Person expected = new Person(); + expected.setFirst("John"); + expected.setLast("Smith"); + assertEquals(person, expected); + } + + @Test + public void givenXmlRepresentationOfMap_whenDeserialize_thenBuildsMap() { + // @formatter:off + String xml = "" + + "" + + " " + + " foo" + + " 10" + + " " + + ""; + // @formatter:on + @SuppressWarnings("unchecked") + Map actual = (Map) xstream.fromXML(xml); + + final Map expected = Collections.singletonMap("foo", 10); + + assertEquals(expected, actual); + } + +} diff --git a/xstream/src/test/resources/attack.xml b/xstream/src/test/resources/attack.xml new file mode 100644 index 0000000000..8a5713648c --- /dev/null +++ b/xstream/src/test/resources/attack.xml @@ -0,0 +1,12 @@ + + foo + + java.lang.Comparable + + + + throwAttackExploitedException + + + diff --git a/xstream/src/test/resources/calculator-attack.xml b/xstream/src/test/resources/calculator-attack.xml new file mode 100644 index 0000000000..ae24843dc6 --- /dev/null +++ b/xstream/src/test/resources/calculator-attack.xml @@ -0,0 +1,16 @@ + + foo + + java.lang.Comparable + + + + open + /Applications/Calculator.app + + + start + + + From ce206fade423f59a4c72f202750264e6ae1cdd4e Mon Sep 17 00:00:00 2001 From: gpq5 Date: Tue, 2 Jul 2019 00:40:57 +0530 Subject: [PATCH 16/74] fix for comparison issue with double --- .../com/baeldung/jackson/json/compare/JsonCompareUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java index 2f2c18e248..4cadac073c 100644 --- a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java +++ b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java @@ -82,7 +82,7 @@ public class JsonCompareUnitTest { if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) { Double d1 = ((NumericNode) o1).asDouble(); Double d2 = ((NumericNode) o2).asDouble(); - if (d1.equals(d2)) { + if (d1.compareTo(d2) == 0) { return 0; } } From 00c4774774e3cc1c68874bafd91e26a965c1781e Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Sat, 15 Jun 2019 19:02:55 -0300 Subject: [PATCH 17/74] Moved Content Negotiation article code from spring-mvc-java to spring-mvc-basics --- spring-mvc-basics/README.md | 3 +- spring-mvc-basics/pom.xml | 1 - .../java/com/baeldung/model/Employee.java | 61 ++++++++++++++++++ .../baeldung/spring/web/config/WebConfig.java | 17 +++++ .../web/controller/EmployeeController.java | 31 +++++++++ .../src/main/resources/application.properties | 8 ++- ...llerContentNegotiationIntegrationTest.java | 63 +++++++++++++++++++ spring-mvc-java/README.md | 1 - .../baeldung/spring/web/config/WebConfig.java | 6 -- .../controller/EmployeeIntegrationTest.java | 51 --------------- 10 files changed, 181 insertions(+), 61 deletions(-) create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/model/Employee.java create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java create mode 100644 spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerContentNegotiationIntegrationTest.java delete mode 100644 spring-mvc-java/src/test/java/com/baeldung/web/controller/EmployeeIntegrationTest.java diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index 997e6a88df..9593fd6222 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -10,4 +10,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) - [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) - [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) -- [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) \ No newline at end of file +- [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) +- [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) \ No newline at end of file diff --git a/spring-mvc-basics/pom.xml b/spring-mvc-basics/pom.xml index d04bdda8f6..8c52c60b65 100644 --- a/spring-mvc-basics/pom.xml +++ b/spring-mvc-basics/pom.xml @@ -30,7 +30,6 @@ javax.servlet jstl - ${jstl.version} org.springframework.boot diff --git a/spring-mvc-basics/src/main/java/com/baeldung/model/Employee.java b/spring-mvc-basics/src/main/java/com/baeldung/model/Employee.java new file mode 100644 index 0000000000..fb0a452219 --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/model/Employee.java @@ -0,0 +1,61 @@ +package com.baeldung.model; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Employee { + + private long id; + private String name; + private String contactNumber; + private String workingArea; + + public Employee() { + super(); + } + + public Employee(final long id, final String name, final String contactNumber, final String workingArea) { + this.id = id; + this.name = name; + this.contactNumber = contactNumber; + this.workingArea = workingArea; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + public String getContactNumber() { + return contactNumber; + } + + public void setContactNumber(final String contactNumber) { + this.contactNumber = contactNumber; + } + + public String getWorkingArea() { + return workingArea; + } + + public void setWorkingArea(final String workingArea) { + this.workingArea = workingArea; + } + + @Override + public String toString() { + return "Employee [id=" + id + ", name=" + name + ", contactNumber=" + contactNumber + ", workingArea=" + workingArea + "]"; + } + +} diff --git a/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java index a56dfe550f..9a321f65a2 100644 --- a/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -3,7 +3,9 @@ package com.baeldung.spring.web.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; +import org.springframework.http.MediaType; import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; @@ -47,4 +49,19 @@ public class WebConfig implements WebMvcConfigurer { bean.setOrder(1); return bean; } + + /** + * Spring Boot allows configuring Content Negotiation using properties + */ + @Override + public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) { + configurer.favorPathExtension(true) + .favorParameter(true) + .parameterName("mediaType") + .ignoreAcceptHeader(false) + .useRegisteredExtensionsOnly(false) + .defaultContentType(MediaType.APPLICATION_JSON) + .mediaType("xml", MediaType.APPLICATION_XML) + .mediaType("json", MediaType.APPLICATION_JSON); + } } \ No newline at end of file diff --git a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java new file mode 100644 index 0000000000..00bbbfbe41 --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java @@ -0,0 +1,31 @@ +package com.baeldung.web.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.baeldung.model.Employee; + +@Controller +public class EmployeeController { + + Map employeeMap = new HashMap<>(); + + @ModelAttribute("employees") + public void initEmployees() { + employeeMap.put(1L, new Employee(1L, "John", "223334411", "rh")); + employeeMap.put(2L, new Employee(2L, "Peter", "22001543", "informatics")); + employeeMap.put(3L, new Employee(3L, "Mike", "223334411", "admin")); + } + + @RequestMapping(value = "/employee/{Id}",produces = { "application/json", "application/xml" }, method = RequestMethod.GET) + public @ResponseBody Employee getEmployeeById(@PathVariable final Long Id) { + return employeeMap.get(Id); + } +} diff --git a/spring-mvc-basics/src/main/resources/application.properties b/spring-mvc-basics/src/main/resources/application.properties index 4de974142e..b8a9be0b40 100644 --- a/spring-mvc-basics/src/main/resources/application.properties +++ b/spring-mvc-basics/src/main/resources/application.properties @@ -1 +1,7 @@ -server.servlet.context-path=/spring-mvc-basics \ No newline at end of file +server.servlet.context-path=/spring-mvc-basics + +### Content Negotiation (already defined programatically) +spring.mvc.pathmatch.use-suffix-pattern=true +#spring.mvc.contentnegotiation.favor-path-extension=true +#spring.mvc.contentnegotiation.favor-parameter=true +#spring.mvc.contentnegotiation.parameter-name=mediaType diff --git a/spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerContentNegotiationIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerContentNegotiationIntegrationTest.java new file mode 100644 index 0000000000..6500955d23 --- /dev/null +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerContentNegotiationIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.web.controller; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +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.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +@SpringBootTest +@AutoConfigureMockMvc +public class EmployeeControllerContentNegotiationIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void whenEndpointUsingJsonSuffixCalled_thenJsonResponseObtained() throws Exception { + this.mockMvc.perform(get("/employee/1.json")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)); + } + + @Test + public void whenEndpointUsingXmlSuffixCalled_thenXmlResponseObtained() throws Exception { + this.mockMvc.perform(get("/employee/1.xml")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)); + } + + @Test + public void whenEndpointUsingJsonParameterCalled_thenJsonResponseObtained() throws Exception { + this.mockMvc.perform(get("/employee/1?mediaType=json")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)); + } + + @Test + public void whenEndpointUsingXmlParameterCalled_thenXmlResponseObtained() throws Exception { + this.mockMvc.perform(get("/employee/1?mediaType=xml")) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)); + } + + @Test + public void whenEndpointUsingJsonAcceptHeaderCalled_thenJsonResponseObtained() throws Exception { + this.mockMvc.perform(get("/employee/1").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)); + } + + @Test + public void whenEndpointUsingXmlAcceptHeaderCalled_thenXmlResponseObtained() throws Exception { + this.mockMvc.perform(get("/employee/1").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE)) + .andExpect(status().isOk()) + .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE)); + } +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 8ba9b5fd1e..8a302e6fa3 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -13,7 +13,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [A Quick Guide to Spring MVC Matrix Variables](http://www.baeldung.com/spring-mvc-matrix-variables) - [Intro to WebSockets with Spring](http://www.baeldung.com/websockets-spring) - [File Upload with Spring MVC](http://www.baeldung.com/spring-file-upload) -- [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) - [Circular Dependencies in Spring](http://www.baeldung.com/circular-dependencies-in-spring) - [Introduction to HtmlUnit](http://www.baeldung.com/htmlunit) - [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java index 96b50f2c37..44fef92917 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java +++ b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -17,7 +17,6 @@ import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; @@ -94,11 +93,6 @@ public class WebConfig implements WebMvcConfigurer { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); } - @Override - public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) { - configurer.favorPathExtension(false).favorParameter(true).parameterName("mediaType").ignoreAcceptHeader(true).useRegisteredExtensionsOnly(false).defaultContentType(MediaType.APPLICATION_JSON).mediaType("xml", MediaType.APPLICATION_XML).mediaType("json", - MediaType.APPLICATION_JSON); - } @Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/EmployeeIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/EmployeeIntegrationTest.java deleted file mode 100644 index 0c2aa3de1b..0000000000 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/EmployeeIntegrationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.baeldung.web.controller; - -import org.junit.Before; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -import com.baeldung.model.Employee; -import com.baeldung.spring.web.config.WebConfig; - -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -@ContextConfiguration(classes = WebConfig.class) -public class EmployeeIntegrationTest { - - @Autowired - private EmployeeController employeeController; - - @Before - public void setup() { - employeeController.initEmployees(); - } - - @Test - public void whenInitEmployees_thenVerifyValuesInitiation() { - - Employee employee1 = employeeController.employeeMap.get(1L); - Employee employee2 = employeeController.employeeMap.get(2L); - Employee employee3 = employeeController.employeeMap.get(3L); - - Assert.assertTrue(employee1.getId() == 1L); - Assert.assertTrue(employee1.getName().equals("John")); - Assert.assertTrue(employee1.getContactNumber().equals("223334411")); - Assert.assertTrue(employee1.getWorkingArea().equals("rh")); - - Assert.assertTrue(employee2.getId() == 2L); - Assert.assertTrue(employee2.getName().equals("Peter")); - Assert.assertTrue(employee2.getContactNumber().equals("22001543")); - Assert.assertTrue(employee2.getWorkingArea().equals("informatics")); - - Assert.assertTrue(employee3.getId() == 3L); - Assert.assertTrue(employee3.getName().equals("Mike")); - Assert.assertTrue(employee3.getContactNumber().equals("223334411")); - Assert.assertTrue(employee3.getWorkingArea().equals("admin")); - } - -} From e84ea4d4c50ab8d14470188857663ba2abd9dc19 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 1 Jul 2019 18:32:49 -0300 Subject: [PATCH 18/74] Moved RequestMapping Shortcut annotations article code from spring-mvc-java to spring-mvc-basics --- spring-mvc-basics/README.md | 3 +- .../RequestMappingShortcutsController.java | 47 +++++++++ ...RequestMapingShortcutsIntegrationTest.java | 97 +++++++++++++++++++ spring-mvc-java/README.md | 1 - .../RequestMappingShortcutsController.java | 47 --------- ...RequestMapingShortcutsIntegrationTest.java | 92 ------------------ 6 files changed, 146 insertions(+), 141 deletions(-) create mode 100644 spring-mvc-basics/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java create mode 100644 spring-mvc-basics/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java delete mode 100644 spring-mvc-java/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java delete mode 100644 spring-mvc-java/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index 9593fd6222..ed3d052306 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -11,4 +11,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) - [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) - [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) -- [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) \ No newline at end of file +- [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) +- [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) \ No newline at end of file diff --git a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java new file mode 100644 index 0000000000..e91a914c6d --- /dev/null +++ b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java @@ -0,0 +1,47 @@ +package com.baeldung.web.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class RequestMappingShortcutsController { + + @GetMapping("/get") + public @ResponseBody ResponseEntity get() { + return new ResponseEntity("GET Response", HttpStatus.OK); + } + + @GetMapping("/get/{id}") + public @ResponseBody ResponseEntity getById(@PathVariable String id) { + return new ResponseEntity("GET Response : " + id, HttpStatus.OK); + } + + @PostMapping("/post") + public @ResponseBody ResponseEntity post() { + return new ResponseEntity("POST Response", HttpStatus.OK); + } + + @PutMapping("/put") + public @ResponseBody ResponseEntity put() { + return new ResponseEntity("PUT Response", HttpStatus.OK); + } + + @DeleteMapping("/delete") + public @ResponseBody ResponseEntity delete() { + return new ResponseEntity("DELETE Response", HttpStatus.OK); + } + + @PatchMapping("/patch") + public @ResponseBody ResponseEntity patch() { + return new ResponseEntity("PATCH Response", HttpStatus.OK); + } + +} diff --git a/spring-mvc-basics/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java new file mode 100644 index 0000000000..3fbb5da75e --- /dev/null +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java @@ -0,0 +1,97 @@ +package com.baeldung.web.controller; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultMatcher; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +public class RequestMapingShortcutsIntegrationTest { + + private MockMvc mockMvc; + + @BeforeEach + public void setup() { + this.mockMvc = MockMvcBuilders.standaloneSetup(new RequestMappingShortcutsController()) + .build(); + } + + @Test + public void giventUrl_whenGetRequest_thenFindGetResponse() throws Exception { + + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/get"); + + ResultMatcher contentMatcher = MockMvcResultMatchers.content() + .string("GET Response"); + + this.mockMvc.perform(builder) + .andExpect(contentMatcher) + .andExpect(MockMvcResultMatchers.status() + .isOk()); + + } + + @Test + public void giventUrl_whenPostRequest_thenFindPostResponse() throws Exception { + + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/post"); + + ResultMatcher contentMatcher = MockMvcResultMatchers.content() + .string("POST Response"); + + this.mockMvc.perform(builder) + .andExpect(contentMatcher) + .andExpect(MockMvcResultMatchers.status() + .isOk()); + + } + + @Test + public void giventUrl_whenPutRequest_thenFindPutResponse() throws Exception { + + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.put("/put"); + + ResultMatcher contentMatcher = MockMvcResultMatchers.content() + .string("PUT Response"); + + this.mockMvc.perform(builder) + .andExpect(contentMatcher) + .andExpect(MockMvcResultMatchers.status() + .isOk()); + + } + + @Test + public void giventUrl_whenDeleteRequest_thenFindDeleteResponse() throws Exception { + + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.delete("/delete"); + + ResultMatcher contentMatcher = MockMvcResultMatchers.content() + .string("DELETE Response"); + + this.mockMvc.perform(builder) + .andExpect(contentMatcher) + .andExpect(MockMvcResultMatchers.status() + .isOk()); + + } + + @Test + public void giventUrl_whenPatchRequest_thenFindPatchResponse() throws Exception { + + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.patch("/patch"); + + ResultMatcher contentMatcher = MockMvcResultMatchers.content() + .string("PATCH Response"); + + this.mockMvc.perform(builder) + .andExpect(contentMatcher) + .andExpect(MockMvcResultMatchers.status() + .isOk()); + + } + +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 8a302e6fa3..6ae700ee03 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -15,7 +15,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [File Upload with Spring MVC](http://www.baeldung.com/spring-file-upload) - [Circular Dependencies in Spring](http://www.baeldung.com/circular-dependencies-in-spring) - [Introduction to HtmlUnit](http://www.baeldung.com/htmlunit) -- [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) - [Upload and Display Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) - [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java deleted file mode 100644 index 5d4cbe9d78..0000000000 --- a/spring-mvc-java/src/main/java/com/baeldung/web/controller/RequestMappingShortcutsController.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.baeldung.web.controller; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class RequestMappingShortcutsController { - - @GetMapping("/get") - public @ResponseBody ResponseEntity get() { - return new ResponseEntity("GET Response", HttpStatus.OK); - } - - @GetMapping("/get/{id}") - public @ResponseBody ResponseEntity getById(@PathVariable String id) { - return new ResponseEntity("GET Response : " + id, HttpStatus.OK); - } - - @PostMapping("/post") - public @ResponseBody ResponseEntity post() { - return new ResponseEntity("POST Response", HttpStatus.OK); - } - - @PutMapping("/put") - public @ResponseBody ResponseEntity put() { - return new ResponseEntity("PUT Response", HttpStatus.OK); - } - - @DeleteMapping("/delete") - public @ResponseBody ResponseEntity delete() { - return new ResponseEntity("DELETE Response", HttpStatus.OK); - } - - @PatchMapping("/patch") - public @ResponseBody ResponseEntity patch() { - return new ResponseEntity("PATCH Response", HttpStatus.OK); - } - -} diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java deleted file mode 100644 index fb21905027..0000000000 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/RequestMapingShortcutsIntegrationTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.baeldung.web.controller; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.ResultMatcher; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import com.baeldung.spring.web.config.WebConfig; - -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -@ContextConfiguration(classes = WebConfig.class) -public class RequestMapingShortcutsIntegrationTest { - - @Autowired - private WebApplicationContext ctx; - - private MockMvc mockMvc; - - @Before - public void setup () { - DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.ctx); - this.mockMvc = builder.build(); - } - - @Test - public void giventUrl_whenGetRequest_thenFindGetResponse() throws Exception { - - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/get"); - - ResultMatcher contentMatcher = MockMvcResultMatchers.content().string("GET Response"); - - this.mockMvc.perform(builder).andExpect(contentMatcher).andExpect(MockMvcResultMatchers.status().isOk()); - - } - - @Test - public void giventUrl_whenPostRequest_thenFindPostResponse() throws Exception { - - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/post"); - - ResultMatcher contentMatcher = MockMvcResultMatchers.content().string("POST Response"); - - this.mockMvc.perform(builder).andExpect(contentMatcher).andExpect(MockMvcResultMatchers.status().isOk()); - - } - - @Test - public void giventUrl_whenPutRequest_thenFindPutResponse() throws Exception { - - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.put("/put"); - - ResultMatcher contentMatcher = MockMvcResultMatchers.content().string("PUT Response"); - - this.mockMvc.perform(builder).andExpect(contentMatcher).andExpect(MockMvcResultMatchers.status().isOk()); - - } - - @Test - public void giventUrl_whenDeleteRequest_thenFindDeleteResponse() throws Exception { - - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.delete("/delete"); - - ResultMatcher contentMatcher = MockMvcResultMatchers.content().string("DELETE Response"); - - this.mockMvc.perform(builder).andExpect(contentMatcher).andExpect(MockMvcResultMatchers.status().isOk()); - - } - - @Test - public void giventUrl_whenPatchRequest_thenFindPatchResponse() throws Exception { - - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.patch("/patch"); - - ResultMatcher contentMatcher = MockMvcResultMatchers.content().string("PATCH Response"); - - this.mockMvc.perform(builder).andExpect(contentMatcher).andExpect(MockMvcResultMatchers.status().isOk()); - - } - -} From e77faf8d99fe2f26cd22cdea1546b77b7f1e2eaa Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 1 Jul 2019 19:35:33 -0300 Subject: [PATCH 19/74] Moved MVC Custom Valitation article code from spring-mvc-java to spring-mvc-basics module --- spring-mvc-basics/README.md | 3 +- .../ContactNumberConstraint.java | 48 +++++------ .../ContactNumberValidator.java | 34 ++++---- .../customvalidator/FieldsValueMatch.java | 0 .../FieldsValueMatchValidator.java | 0 .../java/com/baeldung/model/NewUserForm.java | 5 +- .../com/baeldung/model/ValidatedPhone.java | 44 +++++----- .../web/controller/NewUserController.java | 0 .../controller/ValidatedPhoneController.java | 64 +++++++------- .../main/webapp/WEB-INF/view/phoneHome.jsp | 76 ++++++++--------- .../ClassValidationMvcIntegrationTest.java | 55 ++++++------ .../CustomMVCValidatorIntegrationTest.java | 84 ++++++++++--------- spring-mvc-java/README.md | 1 - 13 files changed, 207 insertions(+), 207 deletions(-) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/customvalidator/ContactNumberConstraint.java (89%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/customvalidator/ContactNumberValidator.java (97%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/customvalidator/FieldsValueMatch.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/customvalidator/FieldsValueMatchValidator.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/model/NewUserForm.java (82%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/model/ValidatedPhone.java (94%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/web/controller/NewUserController.java (100%) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/web/controller/ValidatedPhoneController.java (96%) rename {spring-mvc-java => spring-mvc-basics}/src/main/webapp/WEB-INF/view/phoneHome.jsp (89%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/web/controller/ClassValidationMvcIntegrationTest.java (51%) rename {spring-mvc-java => spring-mvc-basics}/src/test/java/com/baeldung/web/controller/CustomMVCValidatorIntegrationTest.java (63%) diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index ed3d052306..1d5fc98f95 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -12,4 +12,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) - [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) - [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) -- [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) \ No newline at end of file +- [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) +- [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/customvalidator/ContactNumberConstraint.java b/spring-mvc-basics/src/main/java/com/baeldung/customvalidator/ContactNumberConstraint.java similarity index 89% rename from spring-mvc-java/src/main/java/com/baeldung/customvalidator/ContactNumberConstraint.java rename to spring-mvc-basics/src/main/java/com/baeldung/customvalidator/ContactNumberConstraint.java index dbd38c1122..42e441f8f9 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/customvalidator/ContactNumberConstraint.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/customvalidator/ContactNumberConstraint.java @@ -1,24 +1,24 @@ -package com.baeldung.customvalidator; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import javax.validation.Constraint; -import javax.validation.Payload; - -@Documented -@Constraint(validatedBy = ContactNumberValidator.class) -@Target({ElementType.METHOD, ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface ContactNumberConstraint { - - String message() default "Invalid phone number"; - - Class[] groups() default {}; - - Class[] payload() default {}; - -} +package com.baeldung.customvalidator; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Documented +@Constraint(validatedBy = ContactNumberValidator.class) +@Target({ ElementType.METHOD, ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface ContactNumberConstraint { + + String message() default "Invalid phone number"; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/customvalidator/ContactNumberValidator.java b/spring-mvc-basics/src/main/java/com/baeldung/customvalidator/ContactNumberValidator.java similarity index 97% rename from spring-mvc-java/src/main/java/com/baeldung/customvalidator/ContactNumberValidator.java rename to spring-mvc-basics/src/main/java/com/baeldung/customvalidator/ContactNumberValidator.java index dea6b9099b..fe14f3ccf1 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/customvalidator/ContactNumberValidator.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/customvalidator/ContactNumberValidator.java @@ -1,17 +1,17 @@ -package com.baeldung.customvalidator; - -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; - -public class ContactNumberValidator implements ConstraintValidator { - - @Override - public void initialize(ContactNumberConstraint contactNumber) { - } - - @Override - public boolean isValid(String contactField, ConstraintValidatorContext cxt) { - return contactField != null && contactField.matches("[0-9]+") && (contactField.length() > 8) && (contactField.length() < 14); - } - -} +package com.baeldung.customvalidator; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class ContactNumberValidator implements ConstraintValidator { + + @Override + public void initialize(ContactNumberConstraint contactNumber) { + } + + @Override + public boolean isValid(String contactField, ConstraintValidatorContext cxt) { + return contactField != null && contactField.matches("[0-9]+") && (contactField.length() > 8) && (contactField.length() < 14); + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/customvalidator/FieldsValueMatch.java b/spring-mvc-basics/src/main/java/com/baeldung/customvalidator/FieldsValueMatch.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/customvalidator/FieldsValueMatch.java rename to spring-mvc-basics/src/main/java/com/baeldung/customvalidator/FieldsValueMatch.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/customvalidator/FieldsValueMatchValidator.java b/spring-mvc-basics/src/main/java/com/baeldung/customvalidator/FieldsValueMatchValidator.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/customvalidator/FieldsValueMatchValidator.java rename to spring-mvc-basics/src/main/java/com/baeldung/customvalidator/FieldsValueMatchValidator.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/NewUserForm.java b/spring-mvc-basics/src/main/java/com/baeldung/model/NewUserForm.java similarity index 82% rename from spring-mvc-java/src/main/java/com/baeldung/model/NewUserForm.java rename to spring-mvc-basics/src/main/java/com/baeldung/model/NewUserForm.java index 12969b6002..b4fe82ab4a 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/model/NewUserForm.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/model/NewUserForm.java @@ -2,10 +2,7 @@ package com.baeldung.model; import com.baeldung.customvalidator.FieldsValueMatch; -@FieldsValueMatch.List({ - @FieldsValueMatch(field = "password", fieldMatch = "verifyPassword", message = "Passwords do not match!"), - @FieldsValueMatch(field = "email", fieldMatch = "verifyEmail", message = "Email addresses do not match!") -}) +@FieldsValueMatch.List({ @FieldsValueMatch(field = "password", fieldMatch = "verifyPassword", message = "Passwords do not match!"), @FieldsValueMatch(field = "email", fieldMatch = "verifyEmail", message = "Email addresses do not match!") }) public class NewUserForm { private String email; private String verifyEmail; diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/ValidatedPhone.java b/spring-mvc-basics/src/main/java/com/baeldung/model/ValidatedPhone.java similarity index 94% rename from spring-mvc-java/src/main/java/com/baeldung/model/ValidatedPhone.java rename to spring-mvc-basics/src/main/java/com/baeldung/model/ValidatedPhone.java index be702a8517..8cea915e6e 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/model/ValidatedPhone.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/model/ValidatedPhone.java @@ -1,22 +1,22 @@ -package com.baeldung.model; - -import com.baeldung.customvalidator.ContactNumberConstraint; - -public class ValidatedPhone { - - @ContactNumberConstraint - private String phone; - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - @Override - public String toString() { - return phone; - } -} +package com.baeldung.model; + +import com.baeldung.customvalidator.ContactNumberConstraint; + +public class ValidatedPhone { + + @ContactNumberConstraint + private String phone; + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return phone; + } +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/NewUserController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/NewUserController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/NewUserController.java rename to spring-mvc-basics/src/main/java/com/baeldung/web/controller/NewUserController.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/ValidatedPhoneController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/ValidatedPhoneController.java similarity index 96% rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/ValidatedPhoneController.java rename to spring-mvc-basics/src/main/java/com/baeldung/web/controller/ValidatedPhoneController.java index 9b3a6b3a4c..73e1e4bb25 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/web/controller/ValidatedPhoneController.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/ValidatedPhoneController.java @@ -1,32 +1,32 @@ -package com.baeldung.web.controller; - -import com.baeldung.model.ValidatedPhone; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; - -import javax.validation.Valid; - -@Controller -public class ValidatedPhoneController { - - @GetMapping("/validatePhone") - public String loadFormPage(Model m) { - m.addAttribute("validatedPhone", new ValidatedPhone()); - return "phoneHome"; - } - - @PostMapping("/addValidatePhone") - public String submitForm(@Valid ValidatedPhone validatedPhone, BindingResult result, Model m) { - if (result.hasErrors()) { - return "phoneHome"; - } - - m.addAttribute("message", "Successfully saved phone: " + validatedPhone.toString()); - return "phoneHome"; - } - - -} +package com.baeldung.web.controller; + +import javax.validation.Valid; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; + +import com.baeldung.model.ValidatedPhone; + +@Controller +public class ValidatedPhoneController { + + @GetMapping("/validatePhone") + public String loadFormPage(Model m) { + m.addAttribute("validatedPhone", new ValidatedPhone()); + return "phoneHome"; + } + + @PostMapping("/addValidatePhone") + public String submitForm(@Valid ValidatedPhone validatedPhone, BindingResult result, Model m) { + if (result.hasErrors()) { + return "phoneHome"; + } + + m.addAttribute("message", "Successfully saved phone: " + validatedPhone.toString()); + return "phoneHome"; + } + +} diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/phoneHome.jsp b/spring-mvc-basics/src/main/webapp/WEB-INF/view/phoneHome.jsp similarity index 89% rename from spring-mvc-java/src/main/webapp/WEB-INF/view/phoneHome.jsp rename to spring-mvc-basics/src/main/webapp/WEB-INF/view/phoneHome.jsp index b873e9bc5f..ebc9052639 100644 --- a/spring-mvc-java/src/main/webapp/WEB-INF/view/phoneHome.jsp +++ b/spring-mvc-basics/src/main/webapp/WEB-INF/view/phoneHome.jsp @@ -1,38 +1,38 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> - - - - - Sample Form - - - - -
- -

Phone Number

-
${message}
- - - - - - -
- - -
-
- - +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + Sample Form + + + + +
+ +

Phone Number

+
${message}
+ + + + + + +
+ + +
+
+ + diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/ClassValidationMvcIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/ClassValidationMvcIntegrationTest.java similarity index 51% rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/ClassValidationMvcIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/web/controller/ClassValidationMvcIntegrationTest.java index 2cd225a775..24182f492a 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/ClassValidationMvcIntegrationTest.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/ClassValidationMvcIntegrationTest.java @@ -5,46 +5,47 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; public class ClassValidationMvcIntegrationTest { - private MockMvc mockMvc; - - @Before - public void setup(){ - this.mockMvc = MockMvcBuilders.standaloneSetup(new NewUserController()).build(); + private MockMvc mockMvc; + + @BeforeEach + public void setup() { + this.mockMvc = MockMvcBuilders.standaloneSetup(new NewUserController()) + .build(); } - + @Test public void givenMatchingEmailPassword_whenPostNewUserForm_thenOk() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.post("/user") - .accept(MediaType.TEXT_HTML) - .param("email", "john@yahoo.com") - .param("verifyEmail", "john@yahoo.com") - .param("password", "pass") - .param("verifyPassword", "pass")) - .andExpect(model().attribute("message", "Valid form")) - .andExpect(view().name("userHome")) - .andExpect(status().isOk()) - .andDo(print()); + .accept(MediaType.TEXT_HTML) + .param("email", "john@yahoo.com") + .param("verifyEmail", "john@yahoo.com") + .param("password", "pass") + .param("verifyPassword", "pass")) + .andExpect(model().attribute("message", "Valid form")) + .andExpect(view().name("userHome")) + .andExpect(status().isOk()) + .andDo(print()); } - + @Test public void givenNotMatchingEmailPassword_whenPostNewUserForm_thenOk() throws Exception { this.mockMvc.perform(MockMvcRequestBuilders.post("/user") - .accept(MediaType.TEXT_HTML) - .param("email", "john@yahoo.com") - .param("verifyEmail", "john@yahoo.commmm") - .param("password", "pass") - .param("verifyPassword", "passsss")) - .andExpect(model().errorCount(2)) - .andExpect(view().name("userHome")) - .andExpect(status().isOk()) - .andDo(print()); + .accept(MediaType.TEXT_HTML) + .param("email", "john@yahoo.com") + .param("verifyEmail", "john@yahoo.commmm") + .param("password", "pass") + .param("verifyPassword", "passsss")) + .andExpect(model().errorCount(2)) + .andExpect(view().name("userHome")) + .andExpect(status().isOk()) + .andDo(print()); } } diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/CustomMVCValidatorIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/CustomMVCValidatorIntegrationTest.java similarity index 63% rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/CustomMVCValidatorIntegrationTest.java rename to spring-mvc-basics/src/test/java/com/baeldung/web/controller/CustomMVCValidatorIntegrationTest.java index 013cf9c91d..11b72e1650 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/CustomMVCValidatorIntegrationTest.java +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/CustomMVCValidatorIntegrationTest.java @@ -1,41 +1,43 @@ -package com.baeldung.web.controller; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -public class CustomMVCValidatorIntegrationTest { - - private MockMvc mockMvc; - - @Before - public void setup(){ - this.mockMvc = MockMvcBuilders.standaloneSetup(new ValidatedPhoneController()).build(); - } - - @Test - public void givenPhonePageUri_whenMockMvc_thenReturnsPhonePage() throws Exception{ - this.mockMvc.perform(get("/validatePhone")).andExpect(view().name("phoneHome")); - } - - @Test - public void givenPhoneURIWithPostAndFormData_whenMockMVC_thenVerifyErrorResponse() throws Exception { - this.mockMvc.perform(MockMvcRequestBuilders.post("/addValidatePhone"). - accept(MediaType.TEXT_HTML). - param("phoneInput", "123")). - andExpect(model().attributeHasFieldErrorCode("validatedPhone", "phone","ContactNumberConstraint")). - andExpect(view().name("phoneHome")). - andExpect(status().isOk()). - andDo(print()); - } - -} +package com.baeldung.web.controller; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +public class CustomMVCValidatorIntegrationTest { + + private MockMvc mockMvc; + + @BeforeEach + public void setup() { + this.mockMvc = MockMvcBuilders.standaloneSetup(new ValidatedPhoneController()) + .build(); + } + + @Test + public void givenPhonePageUri_whenMockMvc_thenReturnsPhonePage() throws Exception { + this.mockMvc.perform(get("/validatePhone")) + .andExpect(view().name("phoneHome")); + } + + @Test + public void givenPhoneURIWithPostAndFormData_whenMockMVC_thenVerifyErrorResponse() throws Exception { + this.mockMvc.perform(MockMvcRequestBuilders.post("/addValidatePhone") + .accept(MediaType.TEXT_HTML) + .param("phoneInput", "123")) + .andExpect(model().attributeHasFieldErrorCode("validatedPhone", "phone", "ContactNumberConstraint")) + .andExpect(view().name("phoneHome")) + .andExpect(status().isOk()) + .andDo(print()); + } + +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 6ae700ee03..15daac97a5 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -16,7 +16,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Circular Dependencies in Spring](http://www.baeldung.com/circular-dependencies-in-spring) - [Introduction to HtmlUnit](http://www.baeldung.com/htmlunit) - [Upload and Display Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) -- [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) - [The HttpMediaTypeNotAcceptableException in Spring MVC](http://www.baeldung.com/spring-httpmediatypenotacceptable) - [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) From bb2765c4e33d09b2398be17d92860af38c3b6875 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 1 Jul 2019 20:26:45 -0300 Subject: [PATCH 20/74] Moved Using @ResponseStatus article from spring-mvc-java to spring-mvc-basics module --- spring-mvc-basics/README.md | 3 ++- spring-mvc-java/README.md | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index 1d5fc98f95..80db309df2 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -13,4 +13,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) - [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) - [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) -- [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) \ No newline at end of file +- [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) +- [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) \ No newline at end of file diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 15daac97a5..d8a79b9759 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -21,6 +21,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) - [Spring MVC @PathVariable with a dot (.) gets truncated](http://www.baeldung.com/spring-mvc-pathvariable-dot) - [A Quick Example of Spring Websockets’ @SendToUser Annotation](http://www.baeldung.com/spring-websockets-sendtouser) -- [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) - [Working with Date Parameters in Spring](https://www.baeldung.com/spring-date-parameters) - [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml) From dc3c7937172b51303389255f8d6c6cb15352f8dc Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 1 Jul 2019 22:08:02 -0300 Subject: [PATCH 21/74] Moved ModeAttribute article from spring-mvc-java to spring-mvc-basics module --- spring-mvc-basics/README.md | 3 +- .../web/controller/EmployeeController.java | 31 ++++++++++++++++- .../main/webapp/WEB-INF/view/employeeHome.jsp | 33 +++++++++++++++++++ .../main/webapp/WEB-INF/view/employeeView.jsp | 25 ++++++++++++++ spring-mvc-java/README.md | 1 - .../web/controller/EmployeeController.java | 26 ++++++++------- .../main/webapp/WEB-INF/view/employeeHome.jsp | 2 +- .../main/webapp/WEB-INF/view/employeeView.jsp | 5 --- 8 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeHome.jsp create mode 100644 spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeView.jsp diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index 80db309df2..afb71ce63d 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) - [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) - [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) -- [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) \ No newline at end of file +- [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) +- [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) \ No newline at end of file diff --git a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java index 00bbbfbe41..cbea4c98c6 100644 --- a/spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/web/controller/EmployeeController.java @@ -4,11 +4,15 @@ import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.ui.ModelMap; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; import com.baeldung.model.Employee; @@ -24,8 +28,33 @@ public class EmployeeController { employeeMap.put(3L, new Employee(3L, "Mike", "223334411", "admin")); } - @RequestMapping(value = "/employee/{Id}",produces = { "application/json", "application/xml" }, method = RequestMethod.GET) + @RequestMapping(value = "/employee", method = RequestMethod.GET) + public ModelAndView showForm() { + return new ModelAndView("employeeHome", "employee", new Employee()); + } + + @RequestMapping(value = "/employee/{Id}", produces = { "application/json", "application/xml" }, method = RequestMethod.GET) public @ResponseBody Employee getEmployeeById(@PathVariable final Long Id) { return employeeMap.get(Id); } + + @RequestMapping(value = "/addEmployee", method = RequestMethod.POST) + public String submit(@ModelAttribute("employee") final Employee employee, final BindingResult result, final ModelMap model) { + if (result.hasErrors()) { + return "error"; + } + model.addAttribute("name", employee.getName()); + model.addAttribute("contactNumber", employee.getContactNumber()); + model.addAttribute("workingArea", employee.getWorkingArea()); + model.addAttribute("id", employee.getId()); + + employeeMap.put(employee.getId(), employee); + + return "employeeView"; + } + + @ModelAttribute + public void addAttributes(final Model model) { + model.addAttribute("msg", "Welcome to the Netherlands!"); + } } diff --git a/spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeHome.jsp b/spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeHome.jsp new file mode 100644 index 0000000000..fa5812faea --- /dev/null +++ b/spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeHome.jsp @@ -0,0 +1,33 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> + + + +Form Example - Register an Employee + + +

Welcome, Enter The Employee Details

+ + + + + + + + + + + + + + + + + + +
Name
Id
Contact Number
+
+ + + + \ No newline at end of file diff --git a/spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeView.jsp b/spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeView.jsp new file mode 100644 index 0000000000..9a9b879a35 --- /dev/null +++ b/spring-mvc-basics/src/main/webapp/WEB-INF/view/employeeView.jsp @@ -0,0 +1,25 @@ +<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> + + +Spring MVC Form Handling + + + +

Submitted Employee Information

+

${msg}

+ + + + + + + + + + + + + +
Name :${name}
ID :${id}
Contact Number :${contactNumber}
+ + \ No newline at end of file diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index d8a79b9759..f12c904229 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -18,7 +18,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Upload and Display Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) - [The HttpMediaTypeNotAcceptableException in Spring MVC](http://www.baeldung.com/spring-httpmediatypenotacceptable) -- [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) - [Spring MVC @PathVariable with a dot (.) gets truncated](http://www.baeldung.com/spring-mvc-pathvariable-dot) - [A Quick Example of Spring Websockets’ @SendToUser Annotation](http://www.baeldung.com/spring-websockets-sendtouser) - [Working with Date Parameters in Spring](https://www.baeldung.com/spring-date-parameters) diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/EmployeeController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/EmployeeController.java index ef76059567..251287dff8 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/web/controller/EmployeeController.java +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/EmployeeController.java @@ -1,20 +1,29 @@ package com.baeldung.web.controller; -import com.baeldung.model.Employee; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.MatrixVariable; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.servlet.ModelAndView; -import java.util.*; +import com.baeldung.model.Employee; @SessionAttributes("employees") @Controller -@ControllerAdvice public class EmployeeController { Map employeeMap = new HashMap<>(); @@ -35,7 +44,7 @@ public class EmployeeController { public @ResponseBody Employee getEmployeeById(@PathVariable final long Id) { return employeeMap.get(Id); } - + @RequestMapping(value = "/addEmployee", method = RequestMethod.POST) public String submit(@ModelAttribute("employee") final Employee employee, final BindingResult result, final ModelMap model) { if (result.hasErrors()) { @@ -51,11 +60,6 @@ public class EmployeeController { return "employeeView"; } - @ModelAttribute - public void addAttributes(final Model model) { - model.addAttribute("msg", "Welcome to the Netherlands!"); - } - @RequestMapping(value = "/employees/{name}", method = RequestMethod.GET) @ResponseBody public ResponseEntity> getEmployeeByNameAndBeginContactNumber(@PathVariable final String name, @MatrixVariable final String beginContactNumber) { diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeHome.jsp b/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeHome.jsp index 8a32fd12b6..268f0a055a 100644 --- a/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeHome.jsp +++ b/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeHome.jsp @@ -8,7 +8,7 @@

Welcome, Enter The Employee Details

- + diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeView.jsp b/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeView.jsp index 627a9d9ddb..1457bc5fc8 100644 --- a/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeView.jsp +++ b/spring-mvc-java/src/main/webapp/WEB-INF/view/employeeView.jsp @@ -6,7 +6,6 @@

Submitted Employee Information

-

${msg}

Name
@@ -20,10 +19,6 @@ - - - -
Name :Contact Number : ${contactNumber}
Working Area :${workingArea}
\ No newline at end of file From e239fb97633c05393917395b0a17dfadb5c5f826 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 1 Jul 2019 22:30:44 -0300 Subject: [PATCH 22/74] Added Integration test for ModelAttribute article --- ...ntrollerModelAttributeIntegrationTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerModelAttributeIntegrationTest.java diff --git a/spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerModelAttributeIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerModelAttributeIntegrationTest.java new file mode 100644 index 0000000000..5195adabd5 --- /dev/null +++ b/spring-mvc-basics/src/test/java/com/baeldung/web/controller/EmployeeControllerModelAttributeIntegrationTest.java @@ -0,0 +1,40 @@ +package com.baeldung.web.controller; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +import java.util.Arrays; +import java.util.Collection; + +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.junit.jupiter.api.Test; +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.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +@SpringBootTest +@AutoConfigureMockMvc +public class EmployeeControllerModelAttributeIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void givenUrlEncodedFormData_whenAddEmployeeEndpointCalled_thenModelContainsMsgAttribute() throws Exception { + Collection formData = Arrays.asList(new BasicNameValuePair("name", "employeeName"), new BasicNameValuePair("id", "99"), new BasicNameValuePair("contactNumber", "123456789")); + String urlEncodedFormData = EntityUtils.toString(new UrlEncodedFormEntity(formData)); + + mockMvc.perform(post("/addEmployee").contentType(MediaType.APPLICATION_FORM_URLENCODED) + .content(urlEncodedFormData)) + .andExpect(status().isOk()) + .andExpect(view().name("employeeView")) + .andExpect(model().attribute("msg", "Welcome to the Netherlands!")); + } +} From ceb3d9ba789a11d696afde71e5599ec4282ad09c Mon Sep 17 00:00:00 2001 From: gpq5 Date: Tue, 2 Jul 2019 23:25:24 +0530 Subject: [PATCH 23/74] added another example of custom comparator --- .../json/compare/JsonCompareUnitTest.java | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java index 4cadac073c..03d7c63e36 100644 --- a/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java +++ b/jackson-2/src/test/java/com/baeldung/jackson/json/compare/JsonCompareUnitTest.java @@ -12,6 +12,7 @@ import org.junit.Test; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.NumericNode; +import com.fasterxml.jackson.databind.node.TextNode; public class JsonCompareUnitTest { @@ -58,7 +59,7 @@ public class JsonCompareUnitTest { } @Test - public void givenTwoJsonDataObjects_whenComparedUsingCustomComparator_thenEqual() throws IOException { + public void givenTwoJsonDataObjects_whenComparedUsingCustomNumericNodeComparator_thenEqual() throws IOException { ObjectMapper mapper = new ObjectMapper(); String s1 = "{\"name\": \"John\",\"score\":5.0}"; @@ -89,4 +90,37 @@ public class JsonCompareUnitTest { return 1; } } + + @Test + public void givenTwoJsonDataObjects_whenComparedUsingCustomTextNodeComparator_thenEqual() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String s1 = "{\"name\": \"JOHN\",\"score\":5}"; + String s2 = "{\"name\": \"John\",\"score\":5}"; + JsonNode actualObj1 = mapper.readTree(s1); + JsonNode actualObj2 = mapper.readTree(s2); + + TextNodeComparator cmp = new TextNodeComparator(); + + assertNotEquals(actualObj1, actualObj2); + assertTrue(actualObj1.equals(cmp, actualObj2)); + + } + + public class TextNodeComparator implements Comparator { + @Override + public int compare(JsonNode o1, JsonNode o2) { + if (o1.equals(o2)) { + return 0; + } + if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) { + String s1 = ((TextNode) o1).asText(); + String s2 = ((TextNode) o2).asText(); + if (s1.equalsIgnoreCase(s2)) { + return 0; + } + } + return 1; + } + } } From b910336c2701a16e7346f887c6726d69ff47416c Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Wed, 3 Jul 2019 16:16:43 +0300 Subject: [PATCH 24/74] BAEL-2995 - possible lossy conversion - new module java-numbers-2 created --- java-numbers-2/.gitignore | 26 ++++ java-numbers-2/README.md | 6 + java-numbers-2/pom.xml | 135 ++++++++++++++++++ .../ConversionTechniquesUnitTest.java | 0 pom.xml | 2 + 5 files changed, 169 insertions(+) create mode 100644 java-numbers-2/.gitignore create mode 100644 java-numbers-2/README.md create mode 100644 java-numbers-2/pom.xml rename {java-numbers => java-numbers-2}/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java (100%) diff --git a/java-numbers-2/.gitignore b/java-numbers-2/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/java-numbers-2/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/java-numbers-2/README.md b/java-numbers-2/README.md new file mode 100644 index 0000000000..7df6cbd5a2 --- /dev/null +++ b/java-numbers-2/README.md @@ -0,0 +1,6 @@ +========= + +## Java Number 2 + +### Relevant Articles: +- [Lossy Conversion in Java](http://www.baeldung.com/lossy-conversion) \ No newline at end of file diff --git a/java-numbers-2/pom.xml b/java-numbers-2/pom.xml new file mode 100644 index 0000000000..963d281548 --- /dev/null +++ b/java-numbers-2/pom.xml @@ -0,0 +1,135 @@ + + 4.0.0 + java-numbers-2 + 0.1.0-SNAPSHOT + java-numbers-2 + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + log4j + log4j + ${log4j.version} + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator.version} + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.decimal4j + decimal4j + ${decimal4j.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + java-numbers + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + 1.8 + 1.8 + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + 3.6.1 + 1.0.3 + 3.5 + + 3.6.1 + + 1.7.21 + 1.1.7 + + 2.21.0 + 3.0.0-M1 + 3.0.2 + + diff --git a/java-numbers/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java similarity index 100% rename from java-numbers/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java rename to java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java diff --git a/pom.xml b/pom.xml index 9760e06bc1..18a7e5f9a8 100644 --- a/pom.xml +++ b/pom.xml @@ -461,6 +461,7 @@ java-lite java-numbers + java-numbers-2 java-rmi java-spi java-streams @@ -1142,6 +1143,7 @@ java-ee-8-security-api java-lite java-numbers + java-numbers-2 java-rmi java-spi java-streams From e5c3dbb67ca8e1a9cee6c863149ad1bac1b8e676 Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Wed, 3 Jul 2019 16:22:08 +0300 Subject: [PATCH 25/74] BAEL-2995 - possible lossy conversion - fixes --- java-numbers-2/pom.xml | 2 +- .../ConversionTechniquesUnitTest.java | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/java-numbers-2/pom.xml b/java-numbers-2/pom.xml index 963d281548..57f1154f53 100644 --- a/java-numbers-2/pom.xml +++ b/java-numbers-2/pom.xml @@ -64,7 +64,7 @@ - java-numbers + java-numbers-2 src/main/resources diff --git a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java index 9ed714e853..80236af044 100644 --- a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java +++ b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java @@ -9,6 +9,11 @@ public class ConversionTechniquesUnitTest { @Test public void testPrimitiveConversion() { + + long longNum = 24; + short shortNum = (short) longNum; + + assertEquals(shortNum, 24); double doubleNum = 15.6; int integerNum = (int) doubleNum; @@ -16,17 +21,6 @@ public class ConversionTechniquesUnitTest { assertEquals(integerNum, 15); } - @Test - public void testWrapperConversion() { - - Double doubleNum = 10.3; - double dbl = doubleNum.doubleValue(); - int intgr = (int) dbl; - Integer intNum = Integer.valueOf(intgr); - - assertTrue(intNum == 10); - } - @Test public void testWrapperToPrimitiveConversion() { @@ -53,4 +47,16 @@ public class ConversionTechniquesUnitTest { assertEquals(longNum, 16); } + + @Test + public void testWrapperConversion() { + + Double doubleNum = 10.3; + double dbl = doubleNum.doubleValue(); //unboxing + int intgr = (int) dbl; //downcasting + Integer intNum = Integer.valueOf(intgr); + + assertTrue(intNum == 10); + } + } From 33476d699173707cda8389cc22c0817abd736f09 Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Fri, 5 Jul 2019 11:46:09 +0300 Subject: [PATCH 26/74] Removed readme file --- java-numbers-2/README.md | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 java-numbers-2/README.md diff --git a/java-numbers-2/README.md b/java-numbers-2/README.md deleted file mode 100644 index 7df6cbd5a2..0000000000 --- a/java-numbers-2/README.md +++ /dev/null @@ -1,6 +0,0 @@ -========= - -## Java Number 2 - -### Relevant Articles: -- [Lossy Conversion in Java](http://www.baeldung.com/lossy-conversion) \ No newline at end of file From a3e08f7ce0e00a620da8aec922d09a7ab028a06f Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Fri, 5 Jul 2019 18:34:01 +0300 Subject: [PATCH 27/74] BAEL-2995 - possible lossy conversion - fixes --- .../ConversionTechniquesUnitTest.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java index 80236af044..071ea4f9ab 100644 --- a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java +++ b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java @@ -13,12 +13,28 @@ public class ConversionTechniquesUnitTest { long longNum = 24; short shortNum = (short) longNum; - assertEquals(shortNum, 24); + assertEquals(24, shortNum); double doubleNum = 15.6; int integerNum = (int) doubleNum; - assertEquals(integerNum, 15); + assertEquals(15, integerNum); + + long largeLongNum = 32768; + long smallLongNum = -32769; + short shortNum1 = (short) largeLongNum; + short shortNum2 = (short) smallLongNum; + + assertEquals(-32768, shortNum1); + assertEquals(32767, shortNum2); + + long maxLong = Long.MAX_VALUE; + long minLong = Long.MIN_VALUE; + int minInt = (int) maxLong; + int maxInt = (int) minLong; + + assertEquals(-1, minInt); + assertEquals(0, maxInt); } @Test @@ -27,16 +43,12 @@ public class ConversionTechniquesUnitTest { Float floatNum = 17.564f; long longNum = floatNum.longValue(); - assertEquals(longNum, 17l); + assertEquals(17, longNum); Double doubleNum = 15.9999; - int intNum = doubleNum.intValue(); + longNum = doubleNum.longValue(); - assertEquals(intNum, 15); - - longNum = Math.round(doubleNum); - - assertEquals(longNum, 16); + assertEquals(15, longNum); } @Test @@ -45,7 +57,7 @@ public class ConversionTechniquesUnitTest { Double doubleNum = 15.9999; long longNum = Math.round(doubleNum); - assertEquals(longNum, 16); + assertEquals(16, longNum); } @Test From 982e32e49cdbd058003595ffb26fd55f8580c8d9 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 6 Jul 2019 18:24:07 +0530 Subject: [PATCH 28/74] [BAEL-14774] - Updated Hibernate @OneToMany article code --- persistence-modules/hibernate-mapping/pom.xml | 9 ++++++++- .../oneToMany/config/HibernateAnnotationUtil.java | 15 ++++++--------- .../oneToMany/main/HibernateManyisOwningSide.java | 0 .../main/HibernateOneToManyAnnotationMain.java | 0 .../oneToMany/main/HibernateOneisOwningSide.java | 0 .../baeldung/hibernate/oneToMany/model/Cart.java | 0 .../hibernate/oneToMany/model/CartOIO.java | 0 .../baeldung/hibernate/oneToMany/model/Items.java | 0 .../hibernate/oneToMany/model/ItemsOIO.java | 0 .../main/resources/hibernate-annotation.cfg.xml | 10 +++++----- .../{test => main}/resources/hibernate.properties | 0 .../src/main/resources/one_to_many.sql | 0 ...ateOneToManyAnnotationMainIntegrationTest.java | 0 13 files changed, 19 insertions(+), 15 deletions(-) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java (65%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/resources/hibernate-annotation.cfg.xml (67%) rename persistence-modules/hibernate-mapping/src/{test => main}/resources/hibernate.properties (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/main/resources/one_to_many.sql (100%) rename persistence-modules/{spring-hibernate4 => hibernate-mapping}/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java (100%) diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml index bb8ebdab65..bf404e5a9c 100644 --- a/persistence-modules/hibernate-mapping/pom.xml +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -31,6 +31,12 @@ h2 ${h2.version}
+ + org.hsqldb + hsqldb + ${hsqldb.version} + test + org.hibernate @@ -59,7 +65,7 @@ hibernate-mapping - src/test/resources + src/main/resources true @@ -70,6 +76,7 @@ 3.8.0 6.0.16.Final 3.0.1-b11 + 2.3.4 diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java similarity index 65% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java index e522dab48d..46e6824f42 100644 --- a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java @@ -1,8 +1,9 @@ package com.baeldung.hibernate.oneToMany.config; import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; public class HibernateAnnotationUtil { @@ -12,16 +13,12 @@ public class HibernateAnnotationUtil { private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate-annotation.cfg.xml - Configuration configuration = new Configuration(); - configuration.configure("hibernate-annotation.cfg.xml"); - System.out.println("Hibernate Annotation Configuration loaded"); - - ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); - System.out.println("Hibernate Annotation serviceRegistry created"); - - SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry); + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure("hibernate-annotation.cfg.xml").build(); + Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build(); + SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build(); return sessionFactory; + } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); ex.printStackTrace(); diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java diff --git a/persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java rename to persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java diff --git a/persistence-modules/spring-hibernate4/src/main/resources/hibernate-annotation.cfg.xml b/persistence-modules/hibernate-mapping/src/main/resources/hibernate-annotation.cfg.xml similarity index 67% rename from persistence-modules/spring-hibernate4/src/main/resources/hibernate-annotation.cfg.xml rename to persistence-modules/hibernate-mapping/src/main/resources/hibernate-annotation.cfg.xml index 14d853d3fd..9b97c03935 100644 --- a/persistence-modules/spring-hibernate4/src/main/resources/hibernate-annotation.cfg.xml +++ b/persistence-modules/hibernate-mapping/src/main/resources/hibernate-annotation.cfg.xml @@ -4,11 +4,11 @@ "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd"> - com.mysql.jdbc.Driver - mypassword - jdbc:mysql://localhost:3306/spring_hibernate_one_to_many?createDatabaseIfNotExist=true - myuser - org.hibernate.dialect.MySQLDialect + org.h2.Driver + + jdbc:h2:mem:spring_hibernate_one_to_many + sa + org.hibernate.dialect.H2Dialect create thread true diff --git a/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties b/persistence-modules/hibernate-mapping/src/main/resources/hibernate.properties similarity index 100% rename from persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties rename to persistence-modules/hibernate-mapping/src/main/resources/hibernate.properties diff --git a/persistence-modules/spring-hibernate4/src/main/resources/one_to_many.sql b/persistence-modules/hibernate-mapping/src/main/resources/one_to_many.sql similarity index 100% rename from persistence-modules/spring-hibernate4/src/main/resources/one_to_many.sql rename to persistence-modules/hibernate-mapping/src/main/resources/one_to_many.sql diff --git a/persistence-modules/spring-hibernate4/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java similarity index 100% rename from persistence-modules/spring-hibernate4/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java rename to persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java From 42e643a1cf2d8c947f547505b707aab1c3d6071b Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 6 Jul 2019 18:29:05 +0530 Subject: [PATCH 29/74] [BAEL-14774] - Moved article to hibernate-mapping module in README --- persistence-modules/hibernate-mapping/README.md | 1 + persistence-modules/spring-hibernate4/README.md | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/hibernate-mapping/README.md b/persistence-modules/hibernate-mapping/README.md index 203cb2f8e4..c8c49a7838 100644 --- a/persistence-modules/hibernate-mapping/README.md +++ b/persistence-modules/hibernate-mapping/README.md @@ -3,3 +3,4 @@ - [Persisting Maps with Hibernate](https://www.baeldung.com/hibernate-persisting-maps) - [Difference Between @Size, @Length, and @Column(length=value)](https://www.baeldung.com/jpa-size-length-column-differences) +- [Hibernate One to Many Annotation Tutorial](http://www.baeldung.com/hibernate-one-to-many) \ No newline at end of file diff --git a/persistence-modules/spring-hibernate4/README.md b/persistence-modules/spring-hibernate4/README.md index 6f8d83aa9d..426944c149 100644 --- a/persistence-modules/spring-hibernate4/README.md +++ b/persistence-modules/spring-hibernate4/README.md @@ -9,7 +9,6 @@ - [Stored Procedures with Hibernate](http://www.baeldung.com/stored-procedures-with-hibernate-tutorial) - [Hibernate: save, persist, update, merge, saveOrUpdate](http://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate) - [Eager/Lazy Loading In Hibernate](http://www.baeldung.com/hibernate-lazy-eager-loading) -- [Hibernate One to Many Annotation Tutorial](http://www.baeldung.com/hibernate-one-to-many) - [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) ### Quick Start From 8b87952f5b3d8d1d092a102c72d11e990912e124 Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Sat, 6 Jul 2019 17:12:58 +0300 Subject: [PATCH 30/74] BAEL-2995 - possible lossy conversion - assert fix --- .../ConversionTechniquesUnitTest.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java index 071ea4f9ab..6659c379b0 100644 --- a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java +++ b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java @@ -12,29 +12,27 @@ public class ConversionTechniquesUnitTest { long longNum = 24; short shortNum = (short) longNum; - assertEquals(24, shortNum); double doubleNum = 15.6; int integerNum = (int) doubleNum; - assertEquals(15, integerNum); long largeLongNum = 32768; - long smallLongNum = -32769; short shortNum1 = (short) largeLongNum; - short shortNum2 = (short) smallLongNum; - assertEquals(-32768, shortNum1); + + long smallLongNum = -32769; + short shortNum2 = (short) smallLongNum; assertEquals(32767, shortNum2); long maxLong = Long.MAX_VALUE; - long minLong = Long.MIN_VALUE; - int minInt = (int) maxLong; - int maxInt = (int) minLong; + int int1 = (int) maxLong; + assertEquals(-1, int1); - assertEquals(-1, minInt); - assertEquals(0, maxInt); + long minLong = Long.MIN_VALUE; + int int2 = (int) minLong; + assertEquals(0, int2); } @Test @@ -42,12 +40,10 @@ public class ConversionTechniquesUnitTest { Float floatNum = 17.564f; long longNum = floatNum.longValue(); - assertEquals(17, longNum); Double doubleNum = 15.9999; longNum = doubleNum.longValue(); - assertEquals(15, longNum); } @@ -56,7 +52,6 @@ public class ConversionTechniquesUnitTest { Double doubleNum = 15.9999; long longNum = Math.round(doubleNum); - assertEquals(16, longNum); } @@ -67,8 +62,7 @@ public class ConversionTechniquesUnitTest { double dbl = doubleNum.doubleValue(); //unboxing int intgr = (int) dbl; //downcasting Integer intNum = Integer.valueOf(intgr); - - assertTrue(intNum == 10); + assertEquals(Integer.valueOf(10), intNum); } } From aebb5cb88e2d492dcf646a310cad4fc1b7ce541e Mon Sep 17 00:00:00 2001 From: Erik Pragt Date: Mon, 8 Jul 2019 16:23:20 -0500 Subject: [PATCH 31/74] BAEL-14772 Update Spring Data MongoDB article to latest dependencies --- persistence-modules/spring-data-mongodb/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/persistence-modules/spring-data-mongodb/pom.xml b/persistence-modules/spring-data-mongodb/pom.xml index 7156cdf071..33ad3a5267 100644 --- a/persistence-modules/spring-data-mongodb/pom.xml +++ b/persistence-modules/spring-data-mongodb/pom.xml @@ -21,7 +21,7 @@ org.springframework.data spring-data-releasetrain - Lovelace-SR3 + Lovelace-SR9 pom @@ -95,7 +95,7 @@
- 2.1.2.RELEASE + 2.1.9.RELEASE 4.1.4 1.1.3 1.9.2 From e1bad1ab5376c960ea12e14fb7deceb908a814ce Mon Sep 17 00:00:00 2001 From: Erik Pragt Date: Mon, 8 Jul 2019 16:53:05 -0500 Subject: [PATCH 32/74] BAEL-2883 Fix tests in spring-cloud projects part 3 --- .../basic/SpringContextIntegrationTest.java | 16 ++++++++++++++++ spring-cloud/spring-cloud-aws/.attach_pid23938 | 0 .../gateway/SpringContextIntegrationTest.java | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/SpringContextIntegrationTest.java delete mode 100644 spring-cloud/spring-cloud-aws/.attach_pid23938 create mode 100644 spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextIntegrationTest.java diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..818e313c98 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.archaius.basic; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } + +} diff --git a/spring-cloud/spring-cloud-aws/.attach_pid23938 b/spring-cloud/spring-cloud-aws/.attach_pid23938 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..dc635cd003 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.bootstrap.gateway; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } + +} From d84e1bd4cf6044973f0240374f26519d4b2bd919 Mon Sep 17 00:00:00 2001 From: Erik Pragt Date: Mon, 8 Jul 2019 17:34:55 -0500 Subject: [PATCH 33/74] BAEL-3036 Update Cors with Spring article and create the code --- .../main/java/com/baeldung/cors/Account.java | 9 +++++++ .../com/baeldung/cors/AccountController.java | 24 ++++++++++++++++++ .../java/com/baeldung/cors/WebConfig.java | 16 ++++++++++++ .../main/webapp/WEB-INF/spring-web-config.xml | 25 +++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 spring-rest-simple/src/main/java/com/baeldung/cors/Account.java create mode 100644 spring-rest-simple/src/main/java/com/baeldung/cors/AccountController.java create mode 100644 spring-rest-simple/src/main/java/com/baeldung/cors/WebConfig.java create mode 100644 spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml diff --git a/spring-rest-simple/src/main/java/com/baeldung/cors/Account.java b/spring-rest-simple/src/main/java/com/baeldung/cors/Account.java new file mode 100644 index 0000000000..dc6a541a46 --- /dev/null +++ b/spring-rest-simple/src/main/java/com/baeldung/cors/Account.java @@ -0,0 +1,9 @@ +package com.baeldung.cors; + +public class Account { + private Long id; + + public Account(Long id) { + this.id = id; + } +} diff --git a/spring-rest-simple/src/main/java/com/baeldung/cors/AccountController.java b/spring-rest-simple/src/main/java/com/baeldung/cors/AccountController.java new file mode 100644 index 0000000000..c387eb2121 --- /dev/null +++ b/spring-rest-simple/src/main/java/com/baeldung/cors/AccountController.java @@ -0,0 +1,24 @@ +package com.baeldung.cors; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@CrossOrigin(maxAge = 3600) +@RestController +@RequestMapping("/account") +public class AccountController { + + @CrossOrigin("http://example.com") + @RequestMapping("/{id}") + public Account retrieve(@PathVariable Long id) { + return new Account(id); + } + + @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") + public void remove(@PathVariable Long id) { + // ... + } +} \ No newline at end of file diff --git a/spring-rest-simple/src/main/java/com/baeldung/cors/WebConfig.java b/spring-rest-simple/src/main/java/com/baeldung/cors/WebConfig.java new file mode 100644 index 0000000000..dc579ce4ba --- /dev/null +++ b/spring-rest-simple/src/main/java/com/baeldung/cors/WebConfig.java @@ -0,0 +1,16 @@ +package com.baeldung.cors; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**"); + } +} \ No newline at end of file diff --git a/spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml b/spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml new file mode 100644 index 0000000000..07d50ae1d6 --- /dev/null +++ b/spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + From 4b27a2f33c4061b4ea4c7793d20c77da47ea5a27 Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Tue, 9 Jul 2019 05:36:57 +0100 Subject: [PATCH 34/74] Code samples for advanced quasar article (#7271) --- kotlin-quasar/pom.xml | 23 ++ .../com/baeldung/quasar/ActorsBehaviorTest.kt | 157 +++++++++ .../kotlin/com/baeldung/quasar/ActorsTest.kt | 298 ++++++++++++++++++ .../baeldung/quasar/ReactiveStreamsTest.kt | 135 ++++++++ 4 files changed, 613 insertions(+) create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsBehaviorTest.kt create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsTest.kt create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ReactiveStreamsTest.kt diff --git a/kotlin-quasar/pom.xml b/kotlin-quasar/pom.xml index 44feabd183..a3e5a1ec25 100644 --- a/kotlin-quasar/pom.xml +++ b/kotlin-quasar/pom.xml @@ -45,6 +45,27 @@ junit 4.12 + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + ch.qos.logback + logback-core + ${logback.version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + @@ -116,5 +137,7 @@ 0.8.0 1.3.31 + 1.7.21 + 1.1.7 diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsBehaviorTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsBehaviorTest.kt new file mode 100644 index 0000000000..b4d0288a64 --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsBehaviorTest.kt @@ -0,0 +1,157 @@ +package com.baeldung.quasar + +import co.paralleluniverse.actors.Actor +import co.paralleluniverse.actors.ActorRef +import co.paralleluniverse.actors.behaviors.* +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.strands.SuspendableCallable +import org.junit.Test +import org.slf4j.LoggerFactory +import java.lang.Exception + +class ActorsBehaviorTest { + companion object { + private val LOG = LoggerFactory.getLogger(ActorsBehaviorTest::class.java) + } + + @Test + fun requestReplyHelper() { + data class TestMessage(val input: Int) : RequestMessage() + + val actor = object : Actor("requestReplyActor", null) { + @Suspendable + override fun doRun(): Void? { + while (true) { + val msg = receive() + LOG.info("Processing message: {}", msg) + + RequestReplyHelper.reply(msg, msg.input * 100) + } + } + } + + val actorRef = actor.spawn() + + val result = RequestReplyHelper.call(actorRef, TestMessage(50)) + LOG.info("Received reply: {}", result) + } + + @Test + fun server() { + val actor = ServerActor(object : AbstractServerHandler() { + @Suspendable + override fun handleCall(from: ActorRef<*>?, id: Any?, m: Int?): String { + LOG.info("Called with message: {} from {} with ID {}", m, from, id) + return m.toString() ?: "None" + } + + @Suspendable + override fun handleCast(from: ActorRef<*>?, id: Any?, m: Float?) { + LOG.info("Cast message: {} from {} with ID {}", m, from, id) + } + }) + + val server = actor.spawn() + + LOG.info("Call result: {}", server.call(5)) + server.cast(2.5f) + + server.shutdown() + } + + interface Summer { + fun sum(a: Int, b: Int) : Int + } + + @Test + fun proxyServer() { + val actor = ProxyServerActor(false, object : Summer { + @Synchronized + override fun sum(a: Int, b: Int): Int { + Exception().printStackTrace() + LOG.info("Adding together {} and {}", a, b) + return a + b + } + }) + + val summerActor = actor.spawn() + + val result = (summerActor as Summer).sum(1, 2) + LOG.info("Result: {}", result) + + summerActor.shutdown() + } + + @Test + fun eventSource() { + val actor = EventSourceActor() + val eventSource = actor.spawn() + + eventSource.addHandler { msg -> + LOG.info("Sent message: {}", msg) + } + + val name = "Outside Value" + eventSource.addHandler { msg -> + LOG.info("Also Sent message: {} {}", msg, name) + } + + eventSource.send("Hello") + + eventSource.shutdown() + } + + @Test + fun finiteStateMachine() { + val actor = object : FiniteStateMachineActor() { + @Suspendable + override fun initialState(): SuspendableCallable> { + LOG.info("Starting") + return SuspendableCallable { lockedState() } + } + + @Suspendable + fun lockedState() : SuspendableCallable> { + return receive {msg -> + when (msg) { + "PUSH" -> { + LOG.info("Still locked") + lockedState() + } + "COIN" -> { + LOG.info("Unlocking...") + unlockedState() + } + else -> TERMINATE + } + } + } + + @Suspendable + fun unlockedState() : SuspendableCallable> { + return receive {msg -> + when (msg) { + "PUSH" -> { + LOG.info("Locking") + lockedState() + } + "COIN" -> { + LOG.info("Unlocked") + unlockedState() + } + else -> TERMINATE + } + } + } + } + + val actorRef = actor.spawn() + + listOf("PUSH", "COIN", "COIN", "PUSH", "PUSH").forEach { + LOG.info(it) + actorRef.sendSync(it) + } + + actorRef.shutdown() + } +} diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsTest.kt new file mode 100644 index 0000000000..819a149af3 --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ActorsTest.kt @@ -0,0 +1,298 @@ +package com.baeldung.quasar + +import co.paralleluniverse.actors.* +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.strands.channels.Channels +import org.junit.Assert +import org.junit.Test +import org.slf4j.LoggerFactory +import java.util.concurrent.TimeUnit + +class ActorsTest { + companion object { + private val LOG = LoggerFactory.getLogger(ActorsTest::class.java) + } + + @Test + fun createNoopActor() { + val actor = object : Actor("noopActor", MailboxConfig(5, Channels.OverflowPolicy.THROW)) { + @Suspendable + override fun doRun(): String { + return "Hello" + } + } + + actor.spawn() + + println("Noop Actor: ${actor.get()}") + } + + @Test + fun registerActor() { + val actor = object : Actor("registerActor", null) { + @Suspendable + override fun doRun(): String { + return "Hello" + } + } + + val actorRef = actor.spawn() + actor.register() + + val retrievedRef = ActorRegistry.getActor>("registerActor") + + Assert.assertEquals(actorRef, retrievedRef) + actor.join() + } + + @Test + fun registerActorNewName() { + val actor = object : Actor(null, null) { + @Suspendable + override fun doRun(): String { + return "Hello" + } + } + + val actorRef = actor.spawn() + actor.register("renamedActor") + + val retrievedRef = ActorRegistry.getActor>("renamedActor") + + Assert.assertEquals(actorRef, retrievedRef) + actor.join() + } + + @Test + fun retrieveUnknownActor() { + val retrievedRef = ActorRegistry.getActor>("unknownActor", 1, TimeUnit.SECONDS) + + Assert.assertNull(retrievedRef) + } + + @Test + fun createSimpleActor() { + val actor = object : Actor("simpleActor", null) { + @Suspendable + override fun doRun(): Void? { + val msg = receive() + LOG.info("SimpleActor Received Message: {}", msg) + + return null + } + } + + val actorRef = actor.spawn() + + actorRef.send(1) + + actor.join() + } + + @Test + fun createLoopingActor() { + val actor = object : Actor("loopingActor", null) { + @Suspendable + override fun doRun(): Void? { + while (true) { + val msg = receive() + + if (msg > 0) { + LOG.info("LoopingActor Received Message: {}", msg) + } else { + break + } + } + + return null + } + } + + val actorRef = actor.spawn() + + actorRef.send(3) + actorRef.send(2) + actorRef.send(1) + actorRef.send(0) + + actor.join() + } + + @Test + fun actorBacklog() { + val actor = object : Actor("backlogActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) { + @Suspendable + override fun doRun(): String { + TimeUnit.MILLISECONDS.sleep(500); + LOG.info("Backlog Actor Received: {}", receive()) + + try { + receive() + } catch (e: Throwable) { + LOG.info("==== Exception throws by receive() ====") + e.printStackTrace() + } + + return "No Exception" + } + } + + val actorRef = actor.spawn() + + actorRef.send(1) + actorRef.send(2) + + try { + LOG.info("Backlog Actor: {}", actor.get()) + } catch (e: Exception) { + // Expected + LOG.info("==== Exception throws by get() ====") + e.printStackTrace() + } + } + + @Test + fun actorBacklogTrySend() { + val actor = object : Actor("backlogTrySendActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) { + @Suspendable + override fun doRun(): String { + TimeUnit.MILLISECONDS.sleep(500); + LOG.info("Backlog TrySend Actor Received: {}", receive()) + + return "No Exception" + } + } + + val actorRef = actor.spawn() + + LOG.info("Backlog TrySend 1: {}", actorRef.trySend(1)) + LOG.info("Backlog TrySend 1: {}", actorRef.trySend(2)) + + actor.join() + } + + @Test + fun actorTimeoutReceive() { + val actor = object : Actor("TimeoutReceiveActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) { + @Suspendable + override fun doRun(): String { + LOG.info("Timeout Actor Received: {}", receive(500, TimeUnit.MILLISECONDS)) + + return "Finished" + } + } + + val actorRef = actor.spawn() + + TimeUnit.MILLISECONDS.sleep(300) + actorRef.trySend(1) + + actor.join() + } + + + @Test + fun actorNonBlockingReceive() { + val actor = object : Actor("NonBlockingReceiveActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) { + @Suspendable + override fun doRun(): String { + LOG.info("NonBlocking Actor Received #1: {}", tryReceive()) + TimeUnit.MILLISECONDS.sleep(500) + LOG.info("NonBlocking Actor Received #2: {}", tryReceive()) + + return "Finished" + } + } + + val actorRef = actor.spawn() + + TimeUnit.MILLISECONDS.sleep(300) + actorRef.trySend(1) + + actor.join() + } + + @Test + fun evenActor() { + val actor = object : Actor("EvenActor", null) { + @Suspendable + override fun filterMessage(m: Any?): Int? { + return when (m) { + is Int -> { + if (m % 2 == 0) { + m * 10 + } else { + null + } + } + else -> super.filterMessage(m) + } + } + + @Suspendable + override fun doRun(): Void? { + while (true) { + val msg = receive() + + if (msg > 0) { + LOG.info("EvenActor Received Message: {}", msg) + } else { + break + } + } + + return null + } + } + + val actorRef = actor.spawn() + + actorRef.send(3) + actorRef.send(2) + actorRef.send(1) + actorRef.send(0) + + actor.join() + } + + @Test + fun watchingActors() { + val watched = object : Actor("WatchedActor", null) { + @Suspendable + override fun doRun(): Void? { + LOG.info("WatchedActor Starting") + receive(500, TimeUnit.MILLISECONDS) + LOG.info("WatchedActor Finishing") + return null + } + } + + val watcher = object : Actor("WatcherActor", null) { + @Suspendable + override fun doRun(): Void? { + LOG.info("WatcherActor Listening") + try { + LOG.info("WatcherActor received Message: {}", receive(2, TimeUnit.SECONDS)) + } catch (e: Exception) { + LOG.info("WatcherActor Received Exception", e) + } + return null + } + + @Suspendable + override fun handleLifecycleMessage(m: LifecycleMessage?): Int? { + LOG.info("WatcherActor Received Lifecycle Message: {}", m) + return super.handleLifecycleMessage(m) + } + } + + val watcherRef = watcher.spawn() + TimeUnit.MILLISECONDS.sleep(200) + + val watchedRef = watched.spawn() + watcher.link(watchedRef) + + watched.join() + watcher.join() + } +} diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ReactiveStreamsTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ReactiveStreamsTest.kt new file mode 100644 index 0000000000..83e06bf7d6 --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ReactiveStreamsTest.kt @@ -0,0 +1,135 @@ +package com.baeldung.quasar + +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.kotlin.fiber +import co.paralleluniverse.strands.channels.Channels +import co.paralleluniverse.strands.channels.Topic +import co.paralleluniverse.strands.channels.reactivestreams.ReactiveStreams +import org.junit.Test +import org.reactivestreams.Subscriber +import org.reactivestreams.Subscription +import org.slf4j.LoggerFactory +import java.util.concurrent.TimeUnit + +class ReactiveStreamsTest { + companion object { + private val LOG = LoggerFactory.getLogger(ReactiveStreamsTest::class.java) + } + + @Test + fun publisher() { + val inputChannel = Channels.newChannel(1); + + val publisher = ReactiveStreams.toPublisher(inputChannel) + publisher.subscribe(object : Subscriber { + @Suspendable + override fun onComplete() { + LOG.info("onComplete") + } + + @Suspendable + override fun onSubscribe(s: Subscription) { + LOG.info("onSubscribe: {}", s) + s.request(2) + } + + @Suspendable + override fun onNext(t: String?) { + LOG.info("onNext: {}", t) + } + + @Suspendable + override fun onError(t: Throwable?) { + LOG.info("onError: {}", t) + } + }) + + inputChannel.send("Hello") + inputChannel.send("World") + + TimeUnit.SECONDS.sleep(1) + + inputChannel.close() + } + + @Test + fun publisherTopic() { + val inputTopic = Topic() + + val publisher = ReactiveStreams.toPublisher(inputTopic) + publisher.subscribe(object : Subscriber { + @Suspendable + override fun onComplete() { + LOG.info("onComplete 1") + } + + @Suspendable + override fun onSubscribe(s: Subscription) { + LOG.info("onSubscribe 1: {}", s) + s.request(2) + } + + @Suspendable + override fun onNext(t: String?) { + LOG.info("onNext 1: {}", t) + } + + @Suspendable + override fun onError(t: Throwable?) { + LOG.info("onError 1: {}", t) + } + }) + publisher.subscribe(object : Subscriber { + @Suspendable + override fun onComplete() { + LOG.info("onComplete 2") + } + + @Suspendable + override fun onSubscribe(s: Subscription) { + LOG.info("onSubscribe 2: {}", s) + s.request(2) + } + + @Suspendable + override fun onNext(t: String?) { + LOG.info("onNext 2: {}", t) + } + + @Suspendable + override fun onError(t: Throwable?) { + LOG.info("onError 2: {}", t) + } + }) + + inputTopic.send("Hello") + inputTopic.send("World") + + TimeUnit.SECONDS.sleep(1) + + inputTopic.close() + } + + @Test + fun subscribe() { + val inputChannel = Channels.newChannel(10); + val publisher = ReactiveStreams.toPublisher(inputChannel) + + val channel = ReactiveStreams.subscribe(10, Channels.OverflowPolicy.THROW, publisher) + + fiber @Suspendable { + while (!channel.isClosed) { + val message = channel.receive() + LOG.info("Received: {}", message) + } + LOG.info("Stopped receiving messages") + } + + inputChannel.send("Hello") + inputChannel.send("World") + + TimeUnit.SECONDS.sleep(1) + + inputChannel.close() + } +} From 325c0a4d07c7619010960bcb186a7284f29127ee Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Tue, 9 Jul 2019 10:57:55 +0300 Subject: [PATCH 35/74] BAEL-2995 - possible lossy conversion - variable names fixed --- .../ConversionTechniquesUnitTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java index 6659c379b0..2001f39359 100644 --- a/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java +++ b/java-numbers-2/src/test/java/com/baeldung/lossyconversion/ConversionTechniquesUnitTest.java @@ -19,20 +19,20 @@ public class ConversionTechniquesUnitTest { assertEquals(15, integerNum); long largeLongNum = 32768; - short shortNum1 = (short) largeLongNum; - assertEquals(-32768, shortNum1); + short minShortNum = (short) largeLongNum; + assertEquals(-32768, minShortNum); long smallLongNum = -32769; - short shortNum2 = (short) smallLongNum; - assertEquals(32767, shortNum2); + short maxShortNum = (short) smallLongNum; + assertEquals(32767, maxShortNum); long maxLong = Long.MAX_VALUE; - int int1 = (int) maxLong; - assertEquals(-1, int1); + int minInt = (int) maxLong; + assertEquals(-1, minInt); long minLong = Long.MIN_VALUE; - int int2 = (int) minLong; - assertEquals(0, int2); + int maxInt = (int) minLong; + assertEquals(0, maxInt); } @Test From 0d6d9129c4eefa93a4667597ad60ab225293fd2c Mon Sep 17 00:00:00 2001 From: Erik Pragt Date: Tue, 9 Jul 2019 06:18:29 -0500 Subject: [PATCH 36/74] BAEL-3035 Update Spring Kafka module and article from 2.2.2 to 2.2.7 (#7266) --- spring-kafka/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-kafka/pom.xml b/spring-kafka/pom.xml index 2fb4c776fe..3d08aaa928 100644 --- a/spring-kafka/pom.xml +++ b/spring-kafka/pom.xml @@ -33,7 +33,7 @@ - 2.2.2.RELEASE + 2.2.7.RELEASE \ No newline at end of file From 51e1014b26ead1fe5f77f3ea1513f67d7dc44c54 Mon Sep 17 00:00:00 2001 From: Priyesh Mashelkar Date: Tue, 9 Jul 2019 12:30:29 +0100 Subject: [PATCH 37/74] Mocking a void method with EasyMock Issue: BAEL-2952 --- testing-modules/easymock/pom.xml | 26 ++++++++++ .../testing/easymock/ForecastProcessor.java | 28 +++++++++++ .../baeldung/testing/easymock/Location.java | 33 +++++++++++++ .../easymock/ServiceUnavailableException.java | 7 +++ .../testing/easymock/WeatherService.java | 5 ++ .../easymock/ForecastProcessorUnitTest.java | 49 +++++++++++++++++++ testing-modules/pom.xml | 1 + 7 files changed, 149 insertions(+) create mode 100644 testing-modules/easymock/pom.xml create mode 100644 testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ForecastProcessor.java create mode 100644 testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/Location.java create mode 100644 testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ServiceUnavailableException.java create mode 100644 testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/WeatherService.java create mode 100644 testing-modules/easymock/src/test/java/com/baeldung/testing/easymock/ForecastProcessorUnitTest.java diff --git a/testing-modules/easymock/pom.xml b/testing-modules/easymock/pom.xml new file mode 100644 index 0000000000..2b16dd3a1f --- /dev/null +++ b/testing-modules/easymock/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + com.baeldung + testing-modules + 1.0.0-SNAPSHOT + + easymock + easymock + http://maven.apache.org + + UTF-8 + + + + org.easymock + easymock + 4.0.2 + test + + + diff --git a/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ForecastProcessor.java b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ForecastProcessor.java new file mode 100644 index 0000000000..482e985e5b --- /dev/null +++ b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ForecastProcessor.java @@ -0,0 +1,28 @@ +package com.baeldung.testing.easymock; + +import java.math.BigDecimal; + +public class ForecastProcessor { + private WeatherService weatherService; + + public BigDecimal getMaximumTemperature(String locationName) { + + Location location = new Location(locationName); + + try { + weatherService.populateTemperature(location); + } catch (ServiceUnavailableException e) { + return null; + } + + return location.getMaximumTemparature(); + } + + public WeatherService getWeatherService() { + return weatherService; + } + + public void setWeatherService(WeatherService weatherService) { + this.weatherService = weatherService; + } +} diff --git a/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/Location.java b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/Location.java new file mode 100644 index 0000000000..5f318acd5c --- /dev/null +++ b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/Location.java @@ -0,0 +1,33 @@ +package com.baeldung.testing.easymock; + +import java.math.BigDecimal; + +public class Location { + private String name; + private BigDecimal minimumTemperature; + private BigDecimal maximumTemparature; + + public Location(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public BigDecimal getMinimumTemperature() { + return minimumTemperature; + } + + public void setMinimumTemperature(BigDecimal minimumTemperature) { + this.minimumTemperature = minimumTemperature; + } + + public BigDecimal getMaximumTemparature() { + return maximumTemparature; + } + + public void setMaximumTemparature(BigDecimal maximumTemparature) { + this.maximumTemparature = maximumTemparature; + } +} diff --git a/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ServiceUnavailableException.java b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ServiceUnavailableException.java new file mode 100644 index 0000000000..abab4bdee8 --- /dev/null +++ b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/ServiceUnavailableException.java @@ -0,0 +1,7 @@ +package com.baeldung.testing.easymock; + +public class ServiceUnavailableException extends Exception { + + private static final long serialVersionUID = 6961151537340723535L; + +} diff --git a/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/WeatherService.java b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/WeatherService.java new file mode 100644 index 0000000000..1c6b11b17b --- /dev/null +++ b/testing-modules/easymock/src/main/java/com/baeldung/testing/easymock/WeatherService.java @@ -0,0 +1,5 @@ +package com.baeldung.testing.easymock; + +public interface WeatherService { + void populateTemperature(Location location) throws ServiceUnavailableException; +} diff --git a/testing-modules/easymock/src/test/java/com/baeldung/testing/easymock/ForecastProcessorUnitTest.java b/testing-modules/easymock/src/test/java/com/baeldung/testing/easymock/ForecastProcessorUnitTest.java new file mode 100644 index 0000000000..fa8fa847ae --- /dev/null +++ b/testing-modules/easymock/src/test/java/com/baeldung/testing/easymock/ForecastProcessorUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.testing.easymock; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.math.BigDecimal; + +import org.easymock.EasyMock; +import org.easymock.EasyMockRule; +import org.easymock.Mock; +import org.easymock.TestSubject; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class ForecastProcessorUnitTest { + private static int MAX_TEMP = 90; + + @Rule + public EasyMockRule rule = new EasyMockRule(this); + + @TestSubject + private ForecastProcessor forecastProcessor = new ForecastProcessor(); + + @Mock + private WeatherService mockWeatherService; + + @Before + public void setUp() { + forecastProcessor.setWeatherService(mockWeatherService); + } + + @SuppressWarnings("unchecked") + @Test + public void givenLocationName_whenWeatherServicePopulatesTemperatures_thenMaxTempReturned() throws ServiceUnavailableException { + mockWeatherService.populateTemperature(EasyMock.anyObject(Location.class)); + EasyMock.expectLastCall() + .andAnswer(() -> { + Location passedLocation = (Location) EasyMock.getCurrentArguments()[0]; + passedLocation.setMaximumTemparature(new BigDecimal(MAX_TEMP)); + passedLocation.setMinimumTemperature(new BigDecimal(MAX_TEMP - 10)); + return null; + }); + EasyMock.replay(mockWeatherService); + BigDecimal maxTemperature = forecastProcessor.getMaximumTemperature("New York"); + EasyMock.verify(mockWeatherService); + assertThat(maxTemperature, equalTo(new BigDecimal(MAX_TEMP))); + } +} diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index 95a19c2557..bc6e23a6b7 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -33,6 +33,7 @@ testing testng junit-5-basics + easymock junit-5-advanced From a238394e5f94b1aa45c790e0a8f7d5c988f82434 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Wed, 10 Jul 2019 08:56:11 +0300 Subject: [PATCH 38/74] Update README.md --- spring-rest-simple/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-rest-simple/README.md b/spring-rest-simple/README.md index 882d0ac301..c01f27bd98 100644 --- a/spring-rest-simple/README.md +++ b/spring-rest-simple/README.md @@ -5,3 +5,4 @@ - [Spring RequestMapping](http://www.baeldung.com/spring-requestmapping) - [Spring and Apache FileUpload](http://www.baeldung.com/spring-apache-file-upload) - [Test a REST API with curl](http://www.baeldung.com/curl-rest) +- [CORS with Spring](https://www.baeldung.com/spring-cors) From 8510c6172485725b13b0ef234c88383493440e9a Mon Sep 17 00:00:00 2001 From: amit2103 Date: Wed, 10 Jul 2019 12:16:50 +0530 Subject: [PATCH 39/74] [BAEL-15319] - Check modules that don't use our standard parents --- apache-olingo/olingo2/pom.xml | 12 ++++++------ ...a => Olingo2SampleApplicationUnitTest.java} | 2 +- apache-pulsar/pom.xml | 7 +++++++ ...ConsumerTest.java => ConsumerUnitTest.java} | 2 +- ...ProducerTest.java => ProducerUnitTest.java} | 2 +- ...java => ExclusiveSubscriptionUnitTest.java} | 2 +- ....java => FailoverSubscriptionUnitTest.java} | 2 +- .../multimodulemavenproject/daomodule/pom.xml | 9 +++++---- custom-pmd/pom.xml | 6 ++++++ flyway-cdi-extension/pom.xml | 7 +++++++ kotlin-quasar/pom.xml | 6 ++++++ .../maven-polyglot-json-app/pom.json | 8 ++++---- .../maven-polyglot-json-extension/pom.xml | 12 ++++++++++-- maven-polyglot/maven-polyglot-yml-app/pom.yml | 6 ++++++ maven/pom.xml | 6 ++++++ spring-boot-mvc-birt/pom.xml | 9 +++++---- testing-modules/easymock/pom.xml | 18 +++++++++++------- 17 files changed, 84 insertions(+), 32 deletions(-) rename apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/{Olingo2SampleApplicationTests.java => Olingo2SampleApplicationUnitTest.java} (86%) rename apache-pulsar/src/main/java/com/baeldung/{ConsumerTest.java => ConsumerUnitTest.java} (98%) mode change 100755 => 100644 rename apache-pulsar/src/main/java/com/baeldung/{ProducerTest.java => ProducerUnitTest.java} (98%) mode change 100755 => 100644 rename apache-pulsar/src/main/java/com/baeldung/subscriptions/{ExclusiveSubscriptionTest.java => ExclusiveSubscriptionUnitTest.java} (98%) rename apache-pulsar/src/main/java/com/baeldung/subscriptions/{FailoverSubscriptionTest.java => FailoverSubscriptionUnitTest.java} (98%) diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/olingo2/pom.xml index 320f56b717..e3647b9c57 100644 --- a/apache-olingo/olingo2/pom.xml +++ b/apache-olingo/olingo2/pom.xml @@ -9,12 +9,12 @@ olingo2-sample Sample Olingo 2 Project - - org.springframework.boot - spring-boot-starter-parent - 2.1.3.RELEASE - - + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-2 + diff --git a/apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationTests.java b/apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationUnitTest.java similarity index 86% rename from apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationTests.java rename to apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationUnitTest.java index 687f6ab1ff..7cb685e3e9 100644 --- a/apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationTests.java +++ b/apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationUnitTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class Olingo2SampleApplicationTests { +public class Olingo2SampleApplicationUnitTest { @Test public void contextLoads() { diff --git a/apache-pulsar/pom.xml b/apache-pulsar/pom.xml index 11df6d0b87..8a0882dae1 100644 --- a/apache-pulsar/pom.xml +++ b/apache-pulsar/pom.xml @@ -7,6 +7,13 @@ 0.0.1 apache-pulsar + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + org.apache.pulsar diff --git a/apache-pulsar/src/main/java/com/baeldung/ConsumerTest.java b/apache-pulsar/src/main/java/com/baeldung/ConsumerUnitTest.java old mode 100755 new mode 100644 similarity index 98% rename from apache-pulsar/src/main/java/com/baeldung/ConsumerTest.java rename to apache-pulsar/src/main/java/com/baeldung/ConsumerUnitTest.java index 72dc10b542..82a0028837 --- a/apache-pulsar/src/main/java/com/baeldung/ConsumerTest.java +++ b/apache-pulsar/src/main/java/com/baeldung/ConsumerUnitTest.java @@ -7,7 +7,7 @@ import org.apache.pulsar.client.api.Message; import org.apache.pulsar.client.api.PulsarClient; import org.apache.pulsar.client.api.SubscriptionType; -public class ConsumerTest { +public class ConsumerUnitTest { private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String TOPIC_NAME = "test-topic"; diff --git a/apache-pulsar/src/main/java/com/baeldung/ProducerTest.java b/apache-pulsar/src/main/java/com/baeldung/ProducerUnitTest.java old mode 100755 new mode 100644 similarity index 98% rename from apache-pulsar/src/main/java/com/baeldung/ProducerTest.java rename to apache-pulsar/src/main/java/com/baeldung/ProducerUnitTest.java index 08ee0e89b9..10a4b46c4d --- a/apache-pulsar/src/main/java/com/baeldung/ProducerTest.java +++ b/apache-pulsar/src/main/java/com/baeldung/ProducerUnitTest.java @@ -11,7 +11,7 @@ import org.apache.pulsar.client.api.PulsarClientException; import java.io.IOException; import java.util.stream.IntStream; -public class ProducerTest { +public class ProducerUnitTest { private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String TOPIC_NAME = "test-topic"; diff --git a/apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionTest.java b/apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionUnitTest.java similarity index 98% rename from apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionTest.java rename to apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionUnitTest.java index efb898eaf4..79121347e7 100644 --- a/apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionTest.java +++ b/apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionUnitTest.java @@ -10,7 +10,7 @@ import org.apache.pulsar.client.api.SubscriptionType; import java.util.stream.IntStream; -public class ExclusiveSubscriptionTest { +public class ExclusiveSubscriptionUnitTest { private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String TOPIC_NAME = "test-topic"; private static final String SUBSCRIPTION_NAME = "test-subscription"; diff --git a/apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionTest.java b/apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionUnitTest.java similarity index 98% rename from apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionTest.java rename to apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionUnitTest.java index 545661e0c3..1d13b4b83a 100644 --- a/apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionTest.java +++ b/apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionUnitTest.java @@ -11,7 +11,7 @@ import org.apache.pulsar.client.api.SubscriptionType; import java.util.stream.IntStream; -public class FailoverSubscriptionTest { +public class FailoverSubscriptionUnitTest { private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String TOPIC_NAME = "failover-subscription-test-topic"; private static final String SUBSCRIPTION_NAME = "test-subscription"; diff --git a/core-java-modules/multimodulemavenproject/daomodule/pom.xml b/core-java-modules/multimodulemavenproject/daomodule/pom.xml index a260e15e6d..e98c48aa76 100644 --- a/core-java-modules/multimodulemavenproject/daomodule/pom.xml +++ b/core-java-modules/multimodulemavenproject/daomodule/pom.xml @@ -1,15 +1,16 @@ 4.0.0 + com.baeldung.daomodule + daomodule + 1.0 + jar + com.baeldung.multimodulemavenproject multimodulemavenproject 1.0 - com.baeldung.daomodule - daomodule - 1.0 - jar diff --git a/custom-pmd/pom.xml b/custom-pmd/pom.xml index 74e6d9593b..9964bf2bb4 100644 --- a/custom-pmd/pom.xml +++ b/custom-pmd/pom.xml @@ -7,6 +7,12 @@ custom-pmd jar http://maven.apache.org + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + diff --git a/flyway-cdi-extension/pom.xml b/flyway-cdi-extension/pom.xml index f49a51ea4b..f9f951880e 100644 --- a/flyway-cdi-extension/pom.xml +++ b/flyway-cdi-extension/pom.xml @@ -8,6 +8,13 @@ 1.0-SNAPSHOT flyway-cdi-extension + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + javax.enterprise diff --git a/kotlin-quasar/pom.xml b/kotlin-quasar/pom.xml index a3e5a1ec25..231b02b0c7 100644 --- a/kotlin-quasar/pom.xml +++ b/kotlin-quasar/pom.xml @@ -8,6 +8,12 @@ kotlin-quasar jar + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + org.jetbrains.kotlin diff --git a/maven-polyglot/maven-polyglot-json-app/pom.json b/maven-polyglot/maven-polyglot-json-app/pom.json index abd58f3127..3e809b7b83 100644 --- a/maven-polyglot/maven-polyglot-json-app/pom.json +++ b/maven-polyglot/maven-polyglot-json-app/pom.json @@ -5,10 +5,10 @@ "version": "1.0-SNAPSHOT", "name": "Json Maven Polyglot", "parent": { - "groupId": "org.springframework.boot", - "artifactId": "spring-boot-starter-parent", - "version": "2.0.5.RELEASE", - "relativePath": null + "groupId": "com.baeldung", + "artifactId": "parent-boot-2", + "version": "0.0.1-SNAPSHOT", + "relativePath": "../../parent-boot-2" }, "properties": { "project.build.sourceEncoding": "UTF-8", diff --git a/maven-polyglot/maven-polyglot-json-extension/pom.xml b/maven-polyglot/maven-polyglot-json-extension/pom.xml index 5b18529ec5..1170fe7aa6 100644 --- a/maven-polyglot/maven-polyglot-json-extension/pom.xml +++ b/maven-polyglot/maven-polyglot-json-extension/pom.xml @@ -8,17 +8,24 @@ 1.0-SNAPSHOT maven-polyglot-json-extension + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../.. + + org.apache.maven maven-core - 3.5.4 + ${maven-core.version} provided com.fasterxml.jackson.core jackson-databind - 2.9.6 + ${jackson.version} @@ -42,6 +49,7 @@ 1.8 1.8 + 3.5.4 \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-yml-app/pom.yml b/maven-polyglot/maven-polyglot-yml-app/pom.yml index 445e2eec3b..393f7e9e15 100644 --- a/maven-polyglot/maven-polyglot-yml-app/pom.yml +++ b/maven-polyglot/maven-polyglot-yml-app/pom.yml @@ -4,4 +4,10 @@ artifactId: maven-polyglot-yml-app version: 1.0-SNAPSHOT name: 'YAML Demo' +parent: + groupId: "com.baeldung" + artifactId: "parent-modules" + version: "1.0.0-SNAPSHOT" + relativePath: "../.." + properties: {maven.compiler.source: 1.8, maven.compiler.target: 1.8} \ No newline at end of file diff --git a/maven/pom.xml b/maven/pom.xml index ecb031fc11..96643d76f3 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -7,6 +7,12 @@ maven pom + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + custom-rule maven-enforcer diff --git a/spring-boot-mvc-birt/pom.xml b/spring-boot-mvc-birt/pom.xml index 6feb2a7611..bf6bbbf71d 100644 --- a/spring-boot-mvc-birt/pom.xml +++ b/spring-boot-mvc-birt/pom.xml @@ -9,11 +9,12 @@ 0.0.1-SNAPSHOT jar Module For Spring Boot Integration with BIRT - + - org.springframework.boot - spring-boot-starter-parent - 2.1.1.RELEASE + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 diff --git a/testing-modules/easymock/pom.xml b/testing-modules/easymock/pom.xml index 2b16dd3a1f..ed9a077f67 100644 --- a/testing-modules/easymock/pom.xml +++ b/testing-modules/easymock/pom.xml @@ -4,23 +4,27 @@ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 + easymock + easymock + http://maven.apache.org + com.baeldung testing-modules 1.0.0-SNAPSHOT - easymock - easymock - http://maven.apache.org - - UTF-8 - + org.easymock easymock - 4.0.2 + ${easymock.version} test + + + UTF-8 + 4.0.2 + From 3d543356556a319d8d69e0cbf0c2c9719d599707 Mon Sep 17 00:00:00 2001 From: Jon Cook Date: Wed, 10 Jul 2019 12:58:15 +0200 Subject: [PATCH 40/74] BAEL-2912 - TestWatcher API --- .../src/main/resources/logback.xml | 13 ++++ .../TestResultLoggerExtension.java | 62 +++++++++++++++++++ .../testwatcher/TestWatcherAPIUnitTest.java | 36 +++++++++++ 3 files changed, 111 insertions(+) create mode 100644 testing-modules/junit-5-advanced/src/main/resources/logback.xml create mode 100644 testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestResultLoggerExtension.java create mode 100644 testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestWatcherAPIUnitTest.java diff --git a/testing-modules/junit-5-advanced/src/main/resources/logback.xml b/testing-modules/junit-5-advanced/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestResultLoggerExtension.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestResultLoggerExtension.java new file mode 100644 index 0000000000..a92c44a85b --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestResultLoggerExtension.java @@ -0,0 +1,62 @@ +package com.baeldung.extensions.testwatcher; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestWatcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestResultLoggerExtension implements TestWatcher, AfterAllCallback { + + private static final Logger LOG = LoggerFactory.getLogger(TestResultLoggerExtension.class); + + private List testResultsStatus = new ArrayList<>(); + + private enum TestResultStatus { + SUCCESSFUL, ABORTED, FAILED, DISABLED; + } + + @Override + public void testDisabled(ExtensionContext context, Optional reason) { + LOG.info("Test Disabled for test {}: with reason :- {}", context.getDisplayName(), reason.orElse("No reason")); + + testResultsStatus.add(TestResultStatus.DISABLED); + } + + @Override + public void testSuccessful(ExtensionContext context) { + LOG.info("Test Successful for test {}: ", context.getDisplayName()); + + testResultsStatus.add(TestResultStatus.SUCCESSFUL); + } + + @Override + public void testAborted(ExtensionContext context, Throwable cause) { + LOG.info("Test Aborted for test {}: ", context.getDisplayName()); + + testResultsStatus.add(TestResultStatus.ABORTED); + } + + @Override + public void testFailed(ExtensionContext context, Throwable cause) { + LOG.info("Test Aborted for test {}: ", context.getDisplayName()); + + testResultsStatus.add(TestResultStatus.FAILED); + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + Map summary = testResultsStatus.stream() + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); + + LOG.info("Test result summary for {} {}", context.getDisplayName(), summary.toString()); + } + +} diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestWatcherAPIUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestWatcherAPIUnitTest.java new file mode 100644 index 0000000000..89666cf9b8 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/extensions/testwatcher/TestWatcherAPIUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.extensions.testwatcher; + +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.Assert; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(TestResultLoggerExtension.class) +class TestWatcherAPIUnitTest { + + @Test + void givenFalseIsTrue_whenTestAbortedThenCaptureResult() { + Assumptions.assumeTrue(false); + } + + @Disabled + @Test + void givenTrueIsTrue_whenTestDisabledThenCaptureResult() { + Assert.assertTrue(true); + } + + @Test + void givenTrueIsTrue_whenTestAbortedThenCaptureResult() { + Assumptions.assumeTrue(true); + } + + @Disabled("This test is disabled") + @Test + void givenFailure_whenTestDisabledWithReason_ThenCaptureResult() { + fail("Not yet implemented"); + } + +} From 7ebf52f4090015a46ac0abca49f86aac2c24493a Mon Sep 17 00:00:00 2001 From: Kumar Chandrakant Date: Wed, 10 Jul 2019 20:22:01 +0530 Subject: [PATCH 41/74] Adding source code for tutorial tracked by BAEL-2971 (#7250) * Adding source code for tutorial tracked by BAEL-2971 * Renaming Integration Test as par standard --- morphia/README.md | 3 + morphia/pom.xml | 43 ++++++ .../com/baeldung/morphia/domain/Author.java | 31 +++++ .../com/baeldung/morphia/domain/Book.java | 116 ++++++++++++++++ .../baeldung/morphia/domain/Publisher.java | 70 ++++++++++ morphia/src/main/resources/logback.xml | 13 ++ .../morphia/MorphiaIntegrationTest.java | 130 ++++++++++++++++++ pom.xml | 2 + 8 files changed, 408 insertions(+) create mode 100644 morphia/README.md create mode 100644 morphia/pom.xml create mode 100644 morphia/src/main/java/com/baeldung/morphia/domain/Author.java create mode 100644 morphia/src/main/java/com/baeldung/morphia/domain/Book.java create mode 100644 morphia/src/main/java/com/baeldung/morphia/domain/Publisher.java create mode 100644 morphia/src/main/resources/logback.xml create mode 100644 morphia/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java diff --git a/morphia/README.md b/morphia/README.md new file mode 100644 index 0000000000..008cf76c49 --- /dev/null +++ b/morphia/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Intro to Morphia](http://www.baeldung.com/intro-to-morphia) diff --git a/morphia/pom.xml b/morphia/pom.xml new file mode 100644 index 0000000000..e4010a26a1 --- /dev/null +++ b/morphia/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + com.baeldung.morphia + morphia + morphia + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + + + + dev.morphia.morphia + core + ${morphia.version} + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + + + + + 1.4.2.RELEASE + 1.5.3 + + + diff --git a/morphia/src/main/java/com/baeldung/morphia/domain/Author.java b/morphia/src/main/java/com/baeldung/morphia/domain/Author.java new file mode 100644 index 0000000000..b45aee6068 --- /dev/null +++ b/morphia/src/main/java/com/baeldung/morphia/domain/Author.java @@ -0,0 +1,31 @@ +package com.baeldung.morphia.domain; + +import java.util.List; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Id; + +@Entity +public class Author { + + @Id + private String name; + private List books; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } + +} diff --git a/morphia/src/main/java/com/baeldung/morphia/domain/Book.java b/morphia/src/main/java/com/baeldung/morphia/domain/Book.java new file mode 100644 index 0000000000..172c916ad9 --- /dev/null +++ b/morphia/src/main/java/com/baeldung/morphia/domain/Book.java @@ -0,0 +1,116 @@ +package com.baeldung.morphia.domain; + +import java.util.HashSet; +import java.util.Set; + +import dev.morphia.annotations.Embedded; +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Field; +import dev.morphia.annotations.Id; +import dev.morphia.annotations.Index; +import dev.morphia.annotations.IndexOptions; +import dev.morphia.annotations.Indexes; +import dev.morphia.annotations.Property; +import dev.morphia.annotations.Reference; +import dev.morphia.annotations.Validation; + +@Entity("Books") +@Indexes({ @Index(fields = @Field("title"), options = @IndexOptions(name = "book_title")) }) +@Validation("{ price : { $gt : 0 } }") +public class Book { + @Id + private String isbn; + @Property + private String title; + private String author; + @Embedded + private Publisher publisher; + @Property("price") + private double cost; + @Reference + private Set companionBooks; + + public Book() { + + } + + public String getTitle() { + return title; + } + + public String getAuthor() { + return author; + } + + public double getCost() { + return cost; + } + + public void addCompanionBooks(Book book) { + if (companionBooks != null) + this.companionBooks.add(book); + } + + public Book(String isbn, String title, String author, double cost, Publisher publisher) { + this.isbn = isbn; + this.title = title; + this.author = author; + this.cost = cost; + this.publisher = publisher; + this.companionBooks = new HashSet<>(); + } + + @Override + public String toString() { + return "Book [isbn=" + isbn + ", title=" + title + ", author=" + author + ", publisher=" + publisher + ", cost=" + cost + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((author == null) ? 0 : author.hashCode()); + long temp; + temp = Double.doubleToLongBits(cost); + result = prime * result + (int) (temp ^ (temp >>> 32)); + result = prime * result + ((isbn == null) ? 0 : isbn.hashCode()); + result = prime * result + ((publisher == null) ? 0 : publisher.hashCode()); + result = prime * result + ((title == null) ? 0 : title.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Book other = (Book) obj; + if (author == null) { + if (other.author != null) + return false; + } else if (!author.equals(other.author)) + return false; + if (Double.doubleToLongBits(cost) != Double.doubleToLongBits(other.cost)) + return false; + if (isbn == null) { + if (other.isbn != null) + return false; + } else if (!isbn.equals(other.isbn)) + return false; + if (publisher == null) { + if (other.publisher != null) + return false; + } else if (!publisher.equals(other.publisher)) + return false; + if (title == null) { + if (other.title != null) + return false; + } else if (!title.equals(other.title)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/morphia/src/main/java/com/baeldung/morphia/domain/Publisher.java b/morphia/src/main/java/com/baeldung/morphia/domain/Publisher.java new file mode 100644 index 0000000000..b9e054e9ab --- /dev/null +++ b/morphia/src/main/java/com/baeldung/morphia/domain/Publisher.java @@ -0,0 +1,70 @@ +package com.baeldung.morphia.domain; + +import org.bson.types.ObjectId; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Id; + +@Entity +public class Publisher { + + @Id + private ObjectId id; + private String name; + + public Publisher() { + + } + + public Publisher(ObjectId id, String name) { + this.id = id; + this.name = name; + } + + public ObjectId getId() { + return id; + } + + public void setId(ObjectId id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Catalog [id=" + id + ", name=" + name + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Publisher other = (Publisher) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + +} diff --git a/morphia/src/main/resources/logback.xml b/morphia/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/morphia/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/morphia/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java b/morphia/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java new file mode 100644 index 0000000000..a2542a56ab --- /dev/null +++ b/morphia/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java @@ -0,0 +1,130 @@ +package com.baeldung.morphia; + +import static dev.morphia.aggregation.Group.grouping; +import static dev.morphia.aggregation.Group.push; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Iterator; +import java.util.List; + +import org.bson.types.ObjectId; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.baeldung.morphia.domain.Author; +import com.baeldung.morphia.domain.Book; +import com.baeldung.morphia.domain.Publisher; +import com.mongodb.MongoClient; + +import dev.morphia.Datastore; +import dev.morphia.Morphia; +import dev.morphia.query.Query; +import dev.morphia.query.UpdateOperations; + +@Ignore +public class MorphiaIntegrationTest { + + private static Datastore datastore; + private static ObjectId id = new ObjectId(); + + @BeforeClass + public static void setUp() { + Morphia morphia = new Morphia(); + morphia.mapPackage("com.baeldung.morphia"); + datastore = morphia.createDatastore(new MongoClient(), "library"); + datastore.ensureIndexes(); + } + + @Test + public void givenDataSource_whenCreateEntity_thenEntityCreated() { + Publisher publisher = new Publisher(id, "Awsome Publisher"); + Book book = new Book("9781565927186", "Learning Java", "Tom Kirkman", 3.95, publisher); + Book companionBook = new Book("9789332575103", "Java Performance Companion", "Tom Kirkman", 1.95, publisher); + book.addCompanionBooks(companionBook); + datastore.save(companionBook); + datastore.save(book); + + List books = datastore.createQuery(Book.class) + .field("title") + .contains("Learning Java") + .find() + .toList(); + assertEquals(books.size(), 1); + assertEquals(books.get(0), book); + } + + @Test + public void givenDocument_whenUpdated_thenUpdateReflected() { + Publisher publisher = new Publisher(id, "Awsome Publisher"); + Book book = new Book("9781565927186", "Learning Java", "Tom Kirkman", 3.95, publisher); + datastore.save(book); + Query query = datastore.createQuery(Book.class) + .field("title") + .contains("Learning Java"); + UpdateOperations updates = datastore.createUpdateOperations(Book.class) + .inc("price", 1); + datastore.update(query, updates); + List books = datastore.createQuery(Book.class) + .field("title") + .contains("Learning Java") + .find() + .toList(); + assertEquals(books.get(0) + .getCost(), 4.95); + } + + @Test + public void givenDocument_whenDeleted_thenDeleteReflected() { + Publisher publisher = new Publisher(id, "Awsome Publisher"); + Book book = new Book("9781565927186", "Learning Java", "Tom Kirkman", 3.95, publisher); + datastore.save(book); + Query query = datastore.createQuery(Book.class) + .field("title") + .contains("Learning Java"); + datastore.delete(query); + List books = datastore.createQuery(Book.class) + .field("title") + .contains("Learning Java") + .find() + .toList(); + assertEquals(books.size(), 0); + } + + @Test + public void givenDocument_whenAggregated_thenResultsCollected() { + Publisher publisher = new Publisher(id, "Awsome Publisher"); + datastore.save(new Book("9781565927186", "Learning Java", "Tom Kirkman", 3.95, publisher)); + datastore.save(new Book("9781449313142", "Learning Perl", "Mark Pence", 2.95, publisher)); + datastore.save(new Book("9787564100476", "Learning Python", "Mark Pence", 5.95, publisher)); + datastore.save(new Book("9781449368814", "Learning Scala", "Mark Pence", 6.95, publisher)); + datastore.save(new Book("9781784392338", "Learning Go", "Jonathan Sawyer", 8.95, publisher)); + + Iterator authors = datastore.createAggregation(Book.class) + .group("author", grouping("books", push("title"))) + .out(Author.class); + + assertTrue(authors.hasNext()); + + } + + @Test + public void givenDocument_whenProjected_thenOnlyProjectionReceived() { + Publisher publisher = new Publisher(id, "Awsome Publisher"); + Book book = new Book("9781565927186", "Learning Java", "Tom Kirkman", 3.95, publisher); + datastore.save(book); + List books = datastore.createQuery(Book.class) + .field("title") + .contains("Learning Java") + .project("title", true) + .find() + .toList(); + assertEquals(books.size(), 1); + assertEquals("Learning Java", books.get(0) + .getTitle()); + assertEquals(null, books.get(0) + .getAuthor()); + } + +} diff --git a/pom.xml b/pom.xml index b4fed5150d..f24a307d9e 100644 --- a/pom.xml +++ b/pom.xml @@ -558,6 +558,7 @@ tensorflow-java spring-boot-flowable spring-security-kerberos + morphia @@ -791,6 +792,7 @@ tensorflow-java spring-boot-flowable spring-security-kerberos + morphia From 4518645a1f37f734fe7599b906d2759aa31fc313 Mon Sep 17 00:00:00 2001 From: enpy Date: Thu, 11 Jul 2019 08:35:55 +0200 Subject: [PATCH 42/74] BAEL-1780 (#7237) * Singleton injection examples and tests added * code and tests implemented * test refactored * kotlin + jee * kotlin - integration test fixed * fixes * arquillian-kotlin integration fixed * formatting * formatting * data class enhanced --- jee-kotlin/README.md | 1 + jee-kotlin/pom.xml | 289 ++++++++++++++++++ .../com/baeldung/jeekotlin/entity/Student.kt | 22 ++ .../jeekotlin/rest/ApplicationConfig.kt | 9 + .../jeekotlin/rest/StudentResource.kt | 42 +++ .../jeekotlin/service/StudentService.kt | 21 ++ .../main/resources/META-INF/persistence.xml | 18 ++ jee-kotlin/src/main/webapp/WEB-INF/beans.xml | 8 + .../StudentResourceIntegrationTest.java | 108 +++++++ jee-kotlin/src/test/resources/arquillian.xml | 22 ++ 10 files changed, 540 insertions(+) create mode 100644 jee-kotlin/README.md create mode 100644 jee-kotlin/pom.xml create mode 100644 jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/entity/Student.kt create mode 100644 jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/ApplicationConfig.kt create mode 100644 jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/StudentResource.kt create mode 100644 jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/service/StudentService.kt create mode 100644 jee-kotlin/src/main/resources/META-INF/persistence.xml create mode 100644 jee-kotlin/src/main/webapp/WEB-INF/beans.xml create mode 100644 jee-kotlin/src/test/kotlin/com/baeldung/jeekotlin/StudentResourceIntegrationTest.java create mode 100644 jee-kotlin/src/test/resources/arquillian.xml diff --git a/jee-kotlin/README.md b/jee-kotlin/README.md new file mode 100644 index 0000000000..7d843af9ea --- /dev/null +++ b/jee-kotlin/README.md @@ -0,0 +1 @@ +### Relevant Articles: diff --git a/jee-kotlin/pom.xml b/jee-kotlin/pom.xml new file mode 100644 index 0000000000..963c03d0df --- /dev/null +++ b/jee-kotlin/pom.xml @@ -0,0 +1,289 @@ + + + + 4.0.0 + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + jee-kotlin + jee-kotlin + war + + + UTF-8 + false + 8.0 + + + 1.3.41 + official + true + + + 8.2.1.Final + 3.2.3 + 2.21.0 + 3.1.1 + + 1.4.1.Final + 2.0.1.Final + 1.0.0.Alpha4 + + 4.12 + 3.8.0.Final + 2.9.8 + 3.1.3 + + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test-junit + ${kotlin.version} + test + + + junit + junit + ${junit.version} + test + + + javax + javaee-api + ${javaee-api.version} + jar + provided + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + test + + + org.jboss.arquillian.junit + arquillian-junit-container + ${arquillian_core.version} + test + + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-depchain + ${shrinkwrap.version} + pom + test + + + org.jboss.arquillian.extension + arquillian-rest-client-impl-jersey + ${arquillian-rest-client.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + src/main/kotlin + src/test/kotlin + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + + org.apache.maven.plugins + maven-war-plugin + ${mvn-war-plugin.version} + + webapp + kotlin + + + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + + + + + + + org.jboss.arquillian + arquillian-bom + ${arquillian_core.version} + import + pom + + + org.jboss.arquillian.extension + arquillian-drone-bom + ${arquillian-drone-bom.version} + pom + import + + + + + + + wildfly-managed-arquillian + + true + + + + org.wildfly + wildfly-arquillian-container-embedded + ${wildfly.version} + + + org.wildfly + wildfly-embedded + ${wildfly.version} + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + ${maven-dependency-plugin.version} + + + unpack + process-test-classes + + unpack + + + + + org.wildfly + wildfly-dist + ${wildfly.version} + zip + false + target + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + always + + org.jboss.logmanager.LogManager + ${project.basedir}/target/wildfly-${wildfly.version} + ${project.basedir}/target/wildfly-${wildfly.version}/modules + + false + + + + + + + wildfly-remote-arquillian + + + org.jboss.resteasy + resteasy-client + ${resteasy.version} + test + + + org.jboss.resteasy + resteasy-jaxb-provider + ${resteasy.version} + test + + + org.jboss.resteasy + resteasy-json-p-provider + ${resteasy.version} + test + + + org.wildfly.arquillian + wildfly-arquillian-container-remote + 2.2.0.Final + test + + + + + diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/entity/Student.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/entity/Student.kt new file mode 100644 index 0000000000..07f54a39d1 --- /dev/null +++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/entity/Student.kt @@ -0,0 +1,22 @@ +package com.baeldung.jeekotlin.entity + +import com.fasterxml.jackson.annotation.JsonProperty +import javax.persistence.* + +@Entity +data class Student constructor ( + + @SequenceGenerator(name = "student_id_seq", sequenceName = "student_id_seq", allocationSize = 1) + @GeneratedValue(generator = "student_id_seq", strategy = GenerationType.SEQUENCE) + @Id + var id: Long?, + + var firstName: String, + + var lastName: String + +) { + constructor() : this(null, "", "") + + constructor(firstName: String, lastName: String) : this(null, firstName, lastName) +} diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/ApplicationConfig.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/ApplicationConfig.kt new file mode 100644 index 0000000000..12511ed320 --- /dev/null +++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/ApplicationConfig.kt @@ -0,0 +1,9 @@ +package com.baeldung.jeekotlin.rest + +import javax.ws.rs.ApplicationPath +import javax.ws.rs.core.Application + +@ApplicationPath("/") +class ApplicationConfig : Application() { + override fun getClasses() = setOf(StudentResource::class.java) +} diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/StudentResource.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/StudentResource.kt new file mode 100644 index 0000000000..91fa3ff62b --- /dev/null +++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/rest/StudentResource.kt @@ -0,0 +1,42 @@ +package com.baeldung.jeekotlin.rest + +import com.baeldung.jeekotlin.entity.Student +import com.baeldung.jeekotlin.service.StudentService +import javax.inject.Inject +import javax.ws.rs.* +import javax.ws.rs.core.MediaType +import javax.ws.rs.core.Response + +@Path("/student") +open class StudentResource { + + @Inject + private lateinit var service: StudentService + + @POST + open fun create(student: Student): Response { + service.create(student) + return Response.ok().build() + } + + @GET + @Path("/{id}") + open fun read(@PathParam("id") id: Long): Response { + val student = service.read(id) + return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build() + } + + @PUT + open fun update(student: Student): Response { + service.update(student) + return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build() + } + + @DELETE + @Path("/{id}") + open fun delete(@PathParam("id") id: Long): Response { + service.delete(id) + return Response.noContent().build() + } + +} \ No newline at end of file diff --git a/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/service/StudentService.kt b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/service/StudentService.kt new file mode 100644 index 0000000000..3977a45e96 --- /dev/null +++ b/jee-kotlin/src/main/kotlin/com/baeldung/jeekotlin/service/StudentService.kt @@ -0,0 +1,21 @@ +package com.baeldung.jeekotlin.service + +import com.baeldung.jeekotlin.entity.Student +import javax.ejb.Stateless +import javax.persistence.EntityManager +import javax.persistence.PersistenceContext + +@Stateless +open class StudentService { + + @PersistenceContext + private lateinit var entityManager: EntityManager + + open fun create(student: Student) = entityManager.persist(student) + + open fun read(id: Long): Student? = entityManager.find(Student::class.java, id) + + open fun update(student: Student) = entityManager.merge(student) + + open fun delete(id: Long) = entityManager.remove(read(id)) +} \ No newline at end of file diff --git a/jee-kotlin/src/main/resources/META-INF/persistence.xml b/jee-kotlin/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..daac86868b --- /dev/null +++ b/jee-kotlin/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,18 @@ + + + + + + org.hibernate.jpa.HibernatePersistenceProvider + + java:jboss/datasources/ExampleDS + + com.enpy.entity.Student + + + + + + + + diff --git a/jee-kotlin/src/main/webapp/WEB-INF/beans.xml b/jee-kotlin/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..ae0f4bf2ee --- /dev/null +++ b/jee-kotlin/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/jee-kotlin/src/test/kotlin/com/baeldung/jeekotlin/StudentResourceIntegrationTest.java b/jee-kotlin/src/test/kotlin/com/baeldung/jeekotlin/StudentResourceIntegrationTest.java new file mode 100644 index 0000000000..b91b47cb1f --- /dev/null +++ b/jee-kotlin/src/test/kotlin/com/baeldung/jeekotlin/StudentResourceIntegrationTest.java @@ -0,0 +1,108 @@ +package com.baeldung.jeekotlin; + +import com.baeldung.jeekotlin.entity.Student; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Filters; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.Test; +import org.junit.runner.RunWith; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.net.URISyntaxException; +import java.net.URL; + +import static org.junit.Assert.assertEquals; + +@RunWith(Arquillian.class) +public class StudentResourceIntegrationTest { + + @Deployment + public static WebArchive createDeployment() { + JavaArchive[] kotlinRuntime = Maven.configureResolver() + .workOffline() + .withMavenCentralRepo(true) + .withClassPathResolution(true) + .loadPomFromFile("pom.xml") + .resolve("org.jetbrains.kotlin:kotlin-stdlib") + .withTransitivity() + .as(JavaArchive.class); + + return ShrinkWrap.create(WebArchive.class, "kotlin.war") + .addPackages(true, Filters.exclude(".*Test*"), + "com.baeldung.jeekotlin" + ) + .addAsLibraries(kotlinRuntime) + .addAsResource("META-INF/persistence.xml") + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); + } + + @Test + @RunAsClient + public void when_post__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException { + String student = new ObjectMapper().writeValueAsString(new Student("firstName", "lastName")); + WebTarget webTarget = ClientBuilder.newClient().target(url.toURI()); + + Response response = webTarget + .path("/student") + .request(MediaType.APPLICATION_JSON) + .post(Entity.json(student)); + + assertEquals(200, response.getStatus()); + } + + @Test + @RunAsClient + public void when_get__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException { + WebTarget webTarget = ClientBuilder.newClient().target(url.toURI()); + + Response response = webTarget + .path("/student/1") + .request(MediaType.APPLICATION_JSON) + .get(); + + assertEquals(200, response.getStatus()); + } + + @Test + @RunAsClient + public void when_put__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException { + Student student = new Student("firstName", "lastName"); + student.setId(1L); + String studentJson = new ObjectMapper().writeValueAsString(student); + WebTarget webTarget = ClientBuilder.newClient().target(url.toURI()); + + Response response = webTarget + .path("/student") + .request(MediaType.APPLICATION_JSON) + .put(Entity.json(studentJson)); + + assertEquals(200, response.getStatus()); + } + + @Test + @RunAsClient + public void when_delete__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException { + WebTarget webTarget = ClientBuilder.newClient().target(url.toURI()); + + Response response = webTarget + .path("/student/1") + .request() + .delete(); + + assertEquals(204, response.getStatus()); + } + +} \ No newline at end of file diff --git a/jee-kotlin/src/test/resources/arquillian.xml b/jee-kotlin/src/test/resources/arquillian.xml new file mode 100644 index 0000000000..5e6d7c54e8 --- /dev/null +++ b/jee-kotlin/src/test/resources/arquillian.xml @@ -0,0 +1,22 @@ + + + + + target/wildfly-8.2.1.Final + standalone.xml + true + 9990 + + + + + + 127.0.0.1 + 9990 + admin + pass + true + + + + \ No newline at end of file From c1afe47b93f9200cd398a20b0ae0dc434ce2badf Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 11 Jul 2019 15:03:33 +0300 Subject: [PATCH 43/74] remove exception handling --- .../mongodb/services/PhotoService.java | 20 ++++--------- .../mongodb/services/VideoService.java | 24 ++++----------- .../baeldung/mongodb/web/PhotoController.java | 17 ++++------- .../baeldung/mongodb/web/VideoController.java | 30 +++++-------------- 4 files changed, 24 insertions(+), 67 deletions(-) diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/PhotoService.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/PhotoService.java index 685d67c40f..d8d7541c76 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/PhotoService.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/PhotoService.java @@ -1,7 +1,6 @@ package com.baeldung.mongodb.services; import java.io.IOException; -import java.util.Optional; import org.bson.BsonBinarySubType; import org.bson.types.Binary; @@ -19,20 +18,13 @@ public class PhotoService { private PhotoRepository photoRepo; public Photo getPhoto(String id) { - Optional result = photoRepo.findById(id); - return result.isPresent() ? result.get() : null; + return photoRepo.findById(id).get(); } - public String addPhoto(String title, MultipartFile file) { - String id = null; - try { - Photo photo = new Photo(title); - photo.setImage(new Binary(BsonBinarySubType.BINARY, file.getBytes())); - photo = photoRepo.insert(photo); - id = photo.getId(); - } catch (IOException e) { - return null; - } - return id; + public String addPhoto(String title, MultipartFile file) throws IOException { + Photo photo = new Photo(title); + photo.setImage(new Binary(BsonBinarySubType.BINARY, file.getBytes())); + photo = photoRepo.insert(photo); + return photo.getId(); } } diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/VideoService.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/VideoService.java index dea6540973..ade1f7c73a 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/VideoService.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/services/VideoService.java @@ -25,31 +25,19 @@ public class VideoService { @Autowired private GridFsOperations operations; - public Video getVideo(String id) { - Video video = null; + public Video getVideo(String id) throws IllegalStateException, IOException { GridFSFile file = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id))); - if (file != null) { - video = new Video(); - video.setTitle(file.getMetadata().get("title").toString()); - try { - video.setStream(operations.getResource(file).getInputStream()); - } catch (IOException e) { - return null; - } - } + Video video = new Video(); + video.setTitle(file.getMetadata().get("title").toString()); + video.setStream(operations.getResource(file).getInputStream()); return video; } - public String addVideo(String title, MultipartFile file) { + public String addVideo(String title, MultipartFile file) throws IOException { DBObject metaData = new BasicDBObject(); metaData.put("type", "video"); metaData.put("title", title); - ObjectId id; - try { - id = gridFsTemplate.store(file.getInputStream(), file.getName(), file.getContentType(), metaData); - } catch (IOException e) { - return null; - } + ObjectId id = gridFsTemplate.store(file.getInputStream(), file.getName(), file.getContentType(), metaData); return id.toString(); } diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/PhotoController.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/PhotoController.java index fffb6ec320..4d5746f0d8 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/PhotoController.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/PhotoController.java @@ -1,5 +1,6 @@ package com.baeldung.mongodb.web; +import java.io.IOException; import java.util.Base64; import org.springframework.beans.factory.annotation.Autowired; @@ -23,13 +24,9 @@ public class PhotoController { @GetMapping("/photos/{id}") public String getPhoto(@PathVariable String id, Model model) { Photo photo = photoService.getPhoto(id); - if (photo != null) { - model.addAttribute("title", photo.getTitle()); - model.addAttribute("image", Base64.getEncoder().encodeToString(photo.getImage().getData())); - return "photos"; - } - model.addAttribute("message", "Photo not found"); - return "index"; + model.addAttribute("title", photo.getTitle()); + model.addAttribute("image", Base64.getEncoder().encodeToString(photo.getImage().getData())); + return "photos"; } @GetMapping("/photos/upload") @@ -39,12 +36,8 @@ public class PhotoController { } @PostMapping("/photos/add") - public String addPhoto(@RequestParam("title") String title, @RequestParam("image") MultipartFile image, Model model) { + public String addPhoto(@RequestParam("title") String title, @RequestParam("image") MultipartFile image, Model model) throws IOException { String id = photoService.addPhoto(title, image); - if (id == null) { - model.addAttribute("message", "Error Occurred"); - return "index"; - } return "redirect:/photos/" + id; } } diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/VideoController.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/VideoController.java index e5fda0cc64..313ce9e650 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/VideoController.java +++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/mongodb/web/VideoController.java @@ -24,29 +24,17 @@ public class VideoController { private VideoService videoService; @GetMapping("/videos/{id}") - public String getVideo(@PathVariable String id, Model model) { + public String getVideo(@PathVariable String id, Model model) throws IllegalStateException, IOException { Video video = videoService.getVideo(id); - if (video != null) { - model.addAttribute("title", video.getTitle()); - model.addAttribute("url", "/videos/stream/" + id); - return "videos"; - } - model.addAttribute("message", "Video not found"); - return "index"; + model.addAttribute("title", video.getTitle()); + model.addAttribute("url", "/videos/stream/" + id); + return "videos"; } @GetMapping("/videos/stream/{id}") - public void streamVideo(@PathVariable String id, HttpServletResponse response) { + public void streamVideo(@PathVariable String id, HttpServletResponse response) throws IllegalStateException, IOException { Video video = videoService.getVideo(id); - if (video != null) { - try { - FileCopyUtils.copy(video.getStream(), response.getOutputStream()); - } catch (IOException e) { - response.setStatus(500); - } - } else { - response.setStatus(404); - } + FileCopyUtils.copy(video.getStream(), response.getOutputStream()); } @GetMapping("/videos/upload") @@ -56,12 +44,8 @@ public class VideoController { } @PostMapping("/videos/add") - public String addVideo(@RequestParam("title") String title, @RequestParam("file") MultipartFile file, Model model) { + public String addVideo(@RequestParam("title") String title, @RequestParam("file") MultipartFile file, Model model) throws IOException { String id = videoService.addVideo(title, file); - if (id == null) { - model.addAttribute("message", "Error Occurred"); - return "index"; - } return "redirect:/videos/" + id; } } From fc260052b7ad355f1dbace3bf2b11179289d4f46 Mon Sep 17 00:00:00 2001 From: Carlos Cano Date: Thu, 11 Jul 2019 19:00:34 +0200 Subject: [PATCH 44/74] Checking if an array is sorted in java (#7273) * SortedArrayChecker * add recursivity method with custom object * change test names --- .../baeldung/array/SortedArrayChecker.java | 71 ++++++++++++++++++ .../baeldung/arraycopy/model/Employee.java | 15 ++++ .../array/SortedArrayCheckerUnitTest.java | 73 +++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java create mode 100644 core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java diff --git a/core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java b/core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java new file mode 100644 index 0000000000..ec612fd53b --- /dev/null +++ b/core-java-modules/core-java-arrays/src/main/java/com/baeldung/array/SortedArrayChecker.java @@ -0,0 +1,71 @@ +package com.baeldung.array; + +import com.baeldung.arraycopy.model.Employee; + +public class SortedArrayChecker { + boolean isSorted(int[] array, int length) { + if (array == null || length < 2) + return true; + + if (array[length - 2] > array[length - 1]) + return false; + + return isSorted(array, length - 1); + } + + boolean isSorted(int[] array) { + for (int i = 0; i < array.length - 1; i++) { + if (array[i] > array[i + 1]) + return false; + } + + return true; + } + + boolean isSorted(String[] array, int length) { + if (array == null || length < 2) + return true; + + if (array[length - 2].compareTo(array[length - 1]) > 0) + return false; + + return isSorted(array, length - 1); + } + +boolean isSorted(String[] array) { + for (int i = 0; i < array.length - 1; ++i) { + if (array[i].compareTo(array[i + 1]) > 0) + return false; + } + + return true; +} + + boolean isSortedByName(Employee[] array) { + for (int i = 0; i < array.length - 1; ++i) { + if (array[i].getName().compareTo(array[i + 1].getName()) > 0) + return false; + } + + return true; + } + +boolean isSortedByAge(Employee[] array) { + for (int i = 0; i < array.length - 1; ++i) { + if (array[i].getAge() > (array[i + 1].getAge())) + return false; + } + + return true; +} + + boolean isSortedByAge(Employee[] array, int length) { + if (array == null || length < 2) + return true; + + if (array[length - 2].getAge() > array[length - 1].getAge()) + return false; + + return isSortedByAge(array, length - 1); + } +} diff --git a/core-java-modules/core-java-arrays/src/main/java/com/baeldung/arraycopy/model/Employee.java b/core-java-modules/core-java-arrays/src/main/java/com/baeldung/arraycopy/model/Employee.java index a7592574d9..eba39d5716 100644 --- a/core-java-modules/core-java-arrays/src/main/java/com/baeldung/arraycopy/model/Employee.java +++ b/core-java-modules/core-java-arrays/src/main/java/com/baeldung/arraycopy/model/Employee.java @@ -6,6 +6,7 @@ public class Employee implements Serializable { private static final long serialVersionUID = -2454619097207585825L; private int id; private String name; + private int age; public Employee() { } @@ -15,10 +16,24 @@ public class Employee implements Serializable { this.name = name; } + public Employee(int id, String name, int age) { + this.id = id; + this.name = name; + this.age = age; + } + + public int getAge() { + return age; + } + public int getId() { return id; } + public void setAge(int age) { + this.age = age; + } + public void setId(int id) { this.id = id; } diff --git a/core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java b/core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java new file mode 100644 index 0000000000..29866a3c22 --- /dev/null +++ b/core-java-modules/core-java-arrays/src/test/java/com/baeldung/array/SortedArrayCheckerUnitTest.java @@ -0,0 +1,73 @@ +package com.baeldung.array; + +import com.baeldung.arraycopy.model.Employee; +import org.junit.Before; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SortedArrayCheckerUnitTest { + + private static final int[] INTEGER_SORTED = {1, 3, 5, 7, 9}; + private static final int[] INTEGER_NOT_SORTED = {1, 3, 11, 7}; + + private static final String[] STRING_SORTED = {"abc", "cde", "fgh"}; + private static final String[] STRING_NOT_SORTED = {"abc", "fgh", "cde", "ijk"}; + + private final Employee[] EMPLOYEES_SORTED_BY_NAME = { + new Employee(1, "Carlos", 26), + new Employee(2, "Daniel", 31), + new Employee(3, "Marta", 27)}; + + private final Employee[] EMPLOYEES_NOT_SORTED_BY_NAME = { + new Employee(1, "Daniel", 31), + new Employee(2, "Carlos", 26), + new Employee(3, "Marta", 27)}; + + private final Employee[] EMPLOYEES_SORTED_BY_AGE = { + new Employee(1, "Carlos", 26), + new Employee(2, "Marta", 27), + new Employee(3, "Daniel", 31)}; + + private final Employee[] EMPLOYEES_NOT_SORTED_BY_AGE = { + new Employee(1, "Marta", 27), + new Employee(2, "Carlos", 26), + new Employee(3, "Daniel", 31)}; + + private SortedArrayChecker sortedArrayChecker; + + @Before + public void setup() { + sortedArrayChecker = new SortedArrayChecker(); + } + + @Test + public void givenIntegerArray_thenReturnIfItIsSortedOrNot() { + assertThat(sortedArrayChecker.isSorted(INTEGER_SORTED)).isEqualTo(true); + assertThat(sortedArrayChecker.isSorted(INTEGER_NOT_SORTED)).isEqualTo(false); + + assertThat(sortedArrayChecker.isSorted(INTEGER_SORTED, INTEGER_SORTED.length)).isEqualTo(true); + assertThat(sortedArrayChecker.isSorted(INTEGER_NOT_SORTED, INTEGER_NOT_SORTED.length)).isEqualTo(false); + } + + @Test + public void givenStringArray_thenReturnIfItIsSortedOrNot() { + assertThat(sortedArrayChecker.isSorted(STRING_SORTED)).isEqualTo(true); + assertThat(sortedArrayChecker.isSorted(STRING_NOT_SORTED)).isEqualTo(false); + + assertThat(sortedArrayChecker.isSorted(STRING_SORTED, STRING_SORTED.length)).isEqualTo(true); + assertThat(sortedArrayChecker.isSorted(STRING_NOT_SORTED, STRING_NOT_SORTED.length)).isEqualTo(false); + } + + @Test + public void givenEmployeeArray_thenReturnIfItIsSortedOrNot() { + assertThat(sortedArrayChecker.isSortedByName(EMPLOYEES_SORTED_BY_NAME)).isEqualTo(true); + assertThat(sortedArrayChecker.isSortedByName(EMPLOYEES_NOT_SORTED_BY_NAME)).isEqualTo(false); + + assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_SORTED_BY_AGE)).isEqualTo(true); + assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_NOT_SORTED_BY_AGE)).isEqualTo(false); + + assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_SORTED_BY_AGE, EMPLOYEES_SORTED_BY_AGE.length)).isEqualTo(true); + assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_NOT_SORTED_BY_AGE, EMPLOYEES_NOT_SORTED_BY_AGE.length)).isEqualTo(false); + } +} \ No newline at end of file From 9f5986963c6fc1ebcc841ca2c8183546ce0dc5ab Mon Sep 17 00:00:00 2001 From: Rodrigo Graciano Date: Thu, 11 Jul 2019 13:01:56 -0400 Subject: [PATCH 45/74] BAEL-3018 (#7230) * BAEL-3018 * BAEL-3018 * BAEL-3018 * BAEL-3018 * Replace Postgres by H2 * Resolve MongoDB conflict * Method name incorrect * Method name incorrect * Add batch example * Remove unnecesssary code at pom.xml * Organize the code in packages * Replaced Unit with Integration tests --- spring-5-data-reactive/pom.xml | 65 +++++++-- .../com/baeldung/r2dbc/R2dbcApplication.java | 15 +++ .../configuration/R2DBCConfiguration.java | 21 +++ .../java/com/baeldung/r2dbc/model/Player.java | 16 +++ .../r2dbc/repository/PlayerRepository.java | 15 +++ .../R2dbcApplicationIntegrationTest.java | 125 ++++++++++++++++++ 6 files changed, 249 insertions(+), 8 deletions(-) create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/R2dbcApplication.java create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/configuration/R2DBCConfiguration.java create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/model/Player.java create mode 100644 spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/repository/PlayerRepository.java create mode 100644 spring-5-data-reactive/src/test/java/com/baeldung/r2dbc/R2dbcApplicationIntegrationTest.java diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml index 8c16851de0..056fb37a52 100644 --- a/spring-5-data-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -1,9 +1,9 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-5-data-reactive - spring-5-data-reactive + spring-5-data-reactive jar @@ -49,11 +49,11 @@ ${kotlin.version} test - + io.reactivex.rxjava2 rxjava - + org.springframework spring-test @@ -68,6 +68,39 @@ de.flapdoodle.embed.mongo test + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework + spring-tx + 5.2.0.M2 + + + + org.springframework.data + spring-data-r2dbc + 1.0.0.M2 + + + io.r2dbc + r2dbc-h2 + 0.8.0.M8 + + + com.h2database + h2 + 1.4.199 + + + org.springframework.boot + spring-boot-starter-test + test + + @@ -79,7 +112,7 @@ kotlin-maven-plugin ${kotlin-maven-plugin.version} - + compile @@ -123,7 +156,7 @@ - + org.apache.maven.plugins maven-compiler-plugin @@ -131,13 +164,13 @@ ${java.version} - default-compile none - default-testCompile @@ -167,5 +200,21 @@ 1.2.40 + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/R2dbcApplication.java b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/R2dbcApplication.java new file mode 100644 index 0000000000..557b6ff42a --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/R2dbcApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.r2dbc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = "com.baeldung.r2dbc") +public class R2dbcApplication { + + public static void main(String[] args) { + SpringApplication.run(R2dbcApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/configuration/R2DBCConfiguration.java b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/configuration/R2DBCConfiguration.java new file mode 100644 index 0000000000..17eac7fee2 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/configuration/R2DBCConfiguration.java @@ -0,0 +1,21 @@ +package com.baeldung.r2dbc.configuration; + +import io.r2dbc.h2.H2ConnectionConfiguration; +import io.r2dbc.h2.H2ConnectionFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration; +import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; + +@Configuration +//@EnableR2dbcRepositories(basePackages = "com.baeldung.r2dbc.repository") +public class R2DBCConfiguration extends AbstractR2dbcConfiguration { + @Bean + public H2ConnectionFactory connectionFactory() { + return new H2ConnectionFactory( + H2ConnectionConfiguration.builder() + .url("mem:testdb;DB_CLOSE_DELAY=-1;TRACE_LEVEL_FILE=4") + .username("sa") + .build()); + } +} \ No newline at end of file diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/model/Player.java b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/model/Player.java new file mode 100644 index 0000000000..1926997e97 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/model/Player.java @@ -0,0 +1,16 @@ +package com.baeldung.r2dbc.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.Id; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Player { + @Id + Integer id; + String name; + Integer age; +} \ No newline at end of file diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/repository/PlayerRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/repository/PlayerRepository.java new file mode 100644 index 0000000000..33b653140e --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/r2dbc/repository/PlayerRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.r2dbc.repository; + +import com.baeldung.r2dbc.model.Player; +import org.springframework.data.r2dbc.repository.query.Query; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import reactor.core.publisher.Flux; + +public interface PlayerRepository extends ReactiveCrudRepository { + + @Query("select id, name, age from player where name = $1") + Flux findAllByName(String name); + + @Query("select * from player where age = $1") + Flux findByAge(int age); +} \ No newline at end of file diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/r2dbc/R2dbcApplicationIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/r2dbc/R2dbcApplicationIntegrationTest.java new file mode 100644 index 0000000000..a31ef4458d --- /dev/null +++ b/spring-5-data-reactive/src/test/java/com/baeldung/r2dbc/R2dbcApplicationIntegrationTest.java @@ -0,0 +1,125 @@ +package com.baeldung.r2dbc; + + +import com.baeldung.r2dbc.model.Player; +import com.baeldung.r2dbc.repository.PlayerRepository; +import io.r2dbc.h2.H2ConnectionFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.r2dbc.core.DatabaseClient; +import org.springframework.test.context.junit4.SpringRunner; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Hooks; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.util.Arrays; +import java.util.List; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class R2dbcApplicationIntegrationTest { + + + @Autowired + PlayerRepository playerRepository; + + @Autowired + DatabaseClient client; + + @Autowired + H2ConnectionFactory factory; + + + @Before + public void setup() { + + Hooks.onOperatorDebug(); + + List statements = Arrays.asList(// + "DROP TABLE IF EXISTS player;", + "CREATE table player (id INT AUTO_INCREMENT NOT NULL, name VARCHAR2, age INT NOT NULL);"); + + statements.forEach(it -> client.execute() // + .sql(it) // + .fetch() // + .rowsUpdated() // + .as(StepVerifier::create) // + .expectNextCount(1) // + .verifyComplete()); + + } + + @Test + public void whenDeleteAll_then0IsExpected() { + + + playerRepository.deleteAll() + .as(StepVerifier::create) + .expectNextCount(0) + .verifyComplete(); + } + + @Test + public void whenInsert6_then6AreExpected() { + + insertPlayers(); + + playerRepository.findAll() + .as(StepVerifier::create) + .expectNextCount(6) + .verifyComplete(); + } + + @Test + public void whenSearchForCR7_then1IsExpected() { + + insertPlayers(); + + playerRepository.findAllByName("CR7") + .as(StepVerifier::create) + .expectNextCount(1) + .verifyComplete(); + } + + @Test + public void whenSearchFor32YearsOld_then2AreExpected() { + insertPlayers(); + + playerRepository.findByAge(32) + .as(StepVerifier::create) + .expectNextCount(2) + .verifyComplete(); + } + + @Test + public void whenBatchHas2Operations_then2AreExpected() { + Mono.from(factory.create()) + .flatMapMany(connection -> Flux.from(connection + .createBatch() + .add("select * from player") + .add("select * from player") + .execute())) + .as(StepVerifier::create) + .expectNextCount(2) + .verifyComplete(); + + } + + private void insertPlayers() { + List players = Arrays.asList( + new Player(1, "Kaka", 37), + new Player(2, "Messi", 32), + new Player(3, "Mbappé", 20), + new Player(4, "CR7", 34), + new Player(5, "Lewandowski", 30), + new Player(6, "Cavani", 32) + ); + + playerRepository.saveAll(players).subscribe(); + } +} + From 8791269ec70c289acf55691a96a8a0efe19f3352 Mon Sep 17 00:00:00 2001 From: codehunter34 <31874661+codehunter34@users.noreply.github.com> Date: Thu, 11 Jul 2019 13:03:59 -0400 Subject: [PATCH 46/74] BAEL-2850: Difference between vs (#7291) * BAEL-2850: Difference between vs * BAEL-2850: Difference between vs --- .../components/AccountService.java | 2 +- .../components/UserService.java | 2 +- ...{beans.xml => annotationconfigvscomponentscan-beans.xml} | 6 +++--- .../com/baeldung/SpringXMLConfigurationIntegrationTest.java | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) rename spring-5/src/main/java/com/baeldung/{ => annotationconfigvscomponentscan}/components/AccountService.java (59%) rename spring-5/src/main/java/com/baeldung/{ => annotationconfigvscomponentscan}/components/UserService.java (82%) rename spring-5/src/main/resources/{beans.xml => annotationconfigvscomponentscan-beans.xml} (68%) diff --git a/spring-5/src/main/java/com/baeldung/components/AccountService.java b/spring-5/src/main/java/com/baeldung/annotationconfigvscomponentscan/components/AccountService.java similarity index 59% rename from spring-5/src/main/java/com/baeldung/components/AccountService.java rename to spring-5/src/main/java/com/baeldung/annotationconfigvscomponentscan/components/AccountService.java index c2f09c735e..1997163954 100644 --- a/spring-5/src/main/java/com/baeldung/components/AccountService.java +++ b/spring-5/src/main/java/com/baeldung/annotationconfigvscomponentscan/components/AccountService.java @@ -1,4 +1,4 @@ -package com.baeldung.components; +package com.baeldung.annotationconfigvscomponentscan.components; import org.springframework.stereotype.Component; diff --git a/spring-5/src/main/java/com/baeldung/components/UserService.java b/spring-5/src/main/java/com/baeldung/annotationconfigvscomponentscan/components/UserService.java similarity index 82% rename from spring-5/src/main/java/com/baeldung/components/UserService.java rename to spring-5/src/main/java/com/baeldung/annotationconfigvscomponentscan/components/UserService.java index 80e5e0c632..8dd5ae2ef0 100644 --- a/spring-5/src/main/java/com/baeldung/components/UserService.java +++ b/spring-5/src/main/java/com/baeldung/annotationconfigvscomponentscan/components/UserService.java @@ -1,4 +1,4 @@ -package com.baeldung.components; +package com.baeldung.annotationconfigvscomponentscan.components; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/spring-5/src/main/resources/beans.xml b/spring-5/src/main/resources/annotationconfigvscomponentscan-beans.xml similarity index 68% rename from spring-5/src/main/resources/beans.xml rename to spring-5/src/main/resources/annotationconfigvscomponentscan-beans.xml index 004745b817..ee4bbb6573 100644 --- a/spring-5/src/main/resources/beans.xml +++ b/spring-5/src/main/resources/annotationconfigvscomponentscan-beans.xml @@ -4,11 +4,11 @@ - + - + - + diff --git a/spring-5/src/test/java/com/baeldung/SpringXMLConfigurationIntegrationTest.java b/spring-5/src/test/java/com/baeldung/SpringXMLConfigurationIntegrationTest.java index 4ecad9c43e..7cd7b81def 100644 --- a/spring-5/src/test/java/com/baeldung/SpringXMLConfigurationIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/SpringXMLConfigurationIntegrationTest.java @@ -5,14 +5,14 @@ import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; -import com.baeldung.components.AccountService; -import com.baeldung.components.UserService; +import com.baeldung.annotationconfigvscomponentscan.components.AccountService; +import com.baeldung.annotationconfigvscomponentscan.components.UserService; public class SpringXMLConfigurationIntegrationTest { @Test public void givenContextAnnotationConfigOrContextComponentScan_whenDependenciesAndBeansAnnotated_thenNoXMLNeeded() { - ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml"); + ApplicationContext context = new ClassPathXmlApplicationContext("classpath:annotationconfigvscomponentscan-beans.xml"); UserService userService = context.getBean(UserService.class); AccountService accountService = context.getBean(AccountService.class); Assert.assertNotNull(userService); From 7e94de61a95380f26376332bb87de1f13135a5fd Mon Sep 17 00:00:00 2001 From: Sumeet Gajbhar Date: Fri, 12 Jul 2019 02:17:11 +0530 Subject: [PATCH 47/74] BAEL-2885 Spring Cloud Stream with Kakfa (#7114) * BAEL-2927 added logging configuration for tomcat logs * BAEL-2885 coding done * BAEL-2885 formating done * BAEL-2885 scheam namespace fixed * fixed logback issue and added group name in config * updated code to use the correct header for partition key * removed the partition count * updated the code for given comments * BAEL-2885 removed the schema registry client dependency --- .../spring-cloud-stream-kafka/pom.xml | 109 ++++++++++++++++++ .../com/baeldung/AvroKafkaApplication.java | 18 +++ .../baeldung/config/SchemRegistryConfig.java | 18 +++ .../com/baeldung/consumer/AvroConsumer.java | 21 ++++ .../baeldung/controller/AvroController.java | 22 ++++ .../com/baeldung/producer/AvroProducer.java | 42 +++++++ .../src/main/resources/application.yaml | 29 +++++ .../main/resources/employee-key-schema.avsc | 14 +++ .../src/main/resources/employee-schema.avsc | 29 +++++ 9 files changed, 302 insertions(+) create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/config/SchemRegistryConfig.java create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/consumer/AvroConsumer.java create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/controller/AvroController.java create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/producer/AvroProducer.java create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/application.yaml create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-key-schema.avsc create mode 100644 spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-schema.avsc diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml new file mode 100644 index 0000000000..13ad18810e --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + + spring-cloud-stream-kafka + spring-cloud-stream-kafka + Simple Spring Cloud Stream + jar + + + org.springframework.boot + spring-boot-starter-parent + 2.1.5.RELEASE + + + + 1.8 + Greenwich.SR1 + + + + + + org.springframework.cloud + spring-cloud-stream-binder-kafka + + + + org.springframework.cloud + spring-cloud-stream-schema + + + + org.springframework.cloud + spring-cloud-stream-test-support + test + + + + io.confluent + kafka-avro-serializer + 4.0.0 + + + + org.apache.avro + avro-compiler + 1.8.2 + + + + org.apache.avro + avro-maven-plugin + 1.8.2 + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.avro + avro-maven-plugin + 1.8.2 + + + schemas + generate-sources + + schema + protocol + idl-protocol + + + ${project.basedir}/src/main/resources/ + ${project.basedir}/src/main/java/ + + + + + + + + + + confluent + https://packages.confluent.io/maven/ + + + + diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java new file mode 100644 index 0000000000..47c060c143 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/AvroKafkaApplication.java @@ -0,0 +1,18 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.cloud.stream.schema.client.EnableSchemaRegistryClient; + +@SpringBootApplication +@EnableBinding(Processor.class) +@EnableSchemaRegistryClient +public class AvroKafkaApplication { + + public static void main(String[] args) { + SpringApplication.run(AvroKafkaApplication.class, args); + } + +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/config/SchemRegistryConfig.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/config/SchemRegistryConfig.java new file mode 100644 index 0000000000..38ac94d952 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/config/SchemRegistryConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.stream.schema.client.ConfluentSchemaRegistryClient; +import org.springframework.cloud.stream.schema.client.SchemaRegistryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SchemRegistryConfig { + + @Bean + public SchemaRegistryClient schemaRegistryClient(@Value("${spring.cloud.stream.kafka.binder.producer-properties.schema.registry.url}") String endPoint) { + ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient(); + client.setEndpoint(endPoint); + return client; + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/consumer/AvroConsumer.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/consumer/AvroConsumer.java new file mode 100644 index 0000000000..477946dd73 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/consumer/AvroConsumer.java @@ -0,0 +1,21 @@ +package com.baeldung.consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.stereotype.Service; + +import com.baeldung.schema.Employee; + +@Service +public class AvroConsumer { + + private static final Logger LOGGER = LoggerFactory.getLogger(AvroConsumer.class); + + @StreamListener(Processor.INPUT) + public void consumeEmployeeDetails(Employee employeeDetails) { + LOGGER.info("Let's process employee details: {}", employeeDetails); + } + +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/controller/AvroController.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/controller/AvroController.java new file mode 100644 index 0000000000..b98b27c9fe --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/controller/AvroController.java @@ -0,0 +1,22 @@ +package com.baeldung.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.producer.AvroProducer; + +@RestController +public class AvroController { + + @Autowired + private AvroProducer avroProducer; + + @PostMapping("/employees/{id}/{firstName}/{lastName}") + public String producerAvroMessage(@PathVariable int id, @PathVariable String firstName, @PathVariable String lastName) { + avroProducer.produceEmployeeDetails(id, firstName, lastName); + return "Sent employee details to consumer"; + } + +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/producer/AvroProducer.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/producer/AvroProducer.java new file mode 100644 index 0000000000..ff7729dd8c --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/producer/AvroProducer.java @@ -0,0 +1,42 @@ +package com.baeldung.producer; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.stereotype.Service; + +import com.baeldung.schema.Employee; +import com.baeldung.schema.EmployeeKey; + +@Service +public class AvroProducer { + + @Autowired + private Processor processor; + + public void produceEmployeeDetails(int empId, String firstName, String lastName) { + + // creating employee details + Employee employee = new Employee(); + employee.setId(empId); + employee.setFirstName(firstName); + employee.setLastName(lastName); + employee.setDepartment("IT"); + employee.setDesignation("Engineer"); + + // creating partition key for kafka topic + EmployeeKey employeeKey = new EmployeeKey(); + employeeKey.setId(empId); + employeeKey.setDepartmentName("IT"); + + Message message = MessageBuilder.withPayload(employee) + .setHeader(KafkaHeaders.MESSAGE_KEY, employeeKey) + .build(); + + processor.output() + .send(message); + } + +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/application.yaml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/application.yaml new file mode 100644 index 0000000000..2e30c07374 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/application.yaml @@ -0,0 +1,29 @@ +spring: + cloud: + stream: + default: + producer: + useNativeEncoding: true + consumer: + useNativeEncoding: true + bindings: + input: + destination: employee-details + content-type: application/*+avro + group: group-1 + concurrency: 3 + output: + destination: employee-details + content-type: application/*+avro + kafka: + binder: + producer-properties: + key.serializer: io.confluent.kafka.serializers.KafkaAvroSerializer + value.serializer: io.confluent.kafka.serializers.KafkaAvroSerializer + schema.registry.url: http://localhost:8081 + consumer-properties: + key.deserializer: io.confluent.kafka.serializers.KafkaAvroDeserializer + value.deserializer: io.confluent.kafka.serializers.KafkaAvroDeserializer + schema.registry.url: http://localhost:8081 + specific.avro.reader: true + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-key-schema.avsc b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-key-schema.avsc new file mode 100644 index 0000000000..d18d657e99 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-key-schema.avsc @@ -0,0 +1,14 @@ +{ + "type": "record", + "name": "EmployeeKey", + "namespace": "com.baeldung.schema", + "fields": [ + { + "name": "id", + "type": "int" + }, + { + "name": "departmentName", + "type": "string" + }] +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-schema.avsc b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-schema.avsc new file mode 100644 index 0000000000..2abf57e4a2 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/resources/employee-schema.avsc @@ -0,0 +1,29 @@ +{ + "type": "record", + "name": "Employee", + "namespace": "com.baeldung.schema", + "fields": [ + { + "name": "id", + "type": "int" + }, + { + "name": "firstName", + "type": "string" + }, + { + "name": "lastName", + "type": "string" + }, + { + "name": "department", + "type": "string", + "default": "IT " + }, + { + "name": "designation", + "type": "string", + "default": "Software Engineer" + } + ] +} \ No newline at end of file From 5216d789c4fb7feac2fed9159531f0337f48f20c Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 12 Jul 2019 09:31:12 +0200 Subject: [PATCH 48/74] BAEL-2983 move easy-random under testing-modules (#7256) * BAEL-2983 java objects generation with EasyRandom * BAEL-2983 move easy random under testing-modules --- pom.xml | 1 - {easy-random => testing-modules/easy-random}/pom.xml | 1 + .../src/main/java/org/baeldung/easy/random/model/Department.java | 0 .../src/main/java/org/baeldung/easy/random/model/Employee.java | 0 .../src/main/java/org/baeldung/easy/random/model/Grade.java | 0 .../src/main/java/org/baeldung/easy/random/model/Person.java | 0 .../main/java/org/baeldung/easy/random/model/YearQuarter.java | 0 .../baeldung/easy/random/randomizer/YearQuarterRandomizer.java | 0 .../test/java/org/baeldung/easy/random/EasyRandomUnitTest.java | 0 testing-modules/pom.xml | 1 + 10 files changed, 2 insertions(+), 1 deletion(-) rename {easy-random => testing-modules/easy-random}/pom.xml (94%) rename {easy-random => testing-modules/easy-random}/src/main/java/org/baeldung/easy/random/model/Department.java (100%) rename {easy-random => testing-modules/easy-random}/src/main/java/org/baeldung/easy/random/model/Employee.java (100%) rename {easy-random => testing-modules/easy-random}/src/main/java/org/baeldung/easy/random/model/Grade.java (100%) rename {easy-random => testing-modules/easy-random}/src/main/java/org/baeldung/easy/random/model/Person.java (100%) rename {easy-random => testing-modules/easy-random}/src/main/java/org/baeldung/easy/random/model/YearQuarter.java (100%) rename {easy-random => testing-modules/easy-random}/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java (100%) rename {easy-random => testing-modules/easy-random}/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java (100%) diff --git a/pom.xml b/pom.xml index f24a307d9e..d27c4d8a3d 100644 --- a/pom.xml +++ b/pom.xml @@ -422,7 +422,6 @@ drools dubbo - easy-random ethereum feign diff --git a/easy-random/pom.xml b/testing-modules/easy-random/pom.xml similarity index 94% rename from easy-random/pom.xml rename to testing-modules/easy-random/pom.xml index 61f0ed2cd4..93c0027f8f 100644 --- a/easy-random/pom.xml +++ b/testing-modules/easy-random/pom.xml @@ -10,6 +10,7 @@ parent-modules com.baeldung 1.0.0-SNAPSHOT + ../../ diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Department.java b/testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Department.java similarity index 100% rename from easy-random/src/main/java/org/baeldung/easy/random/model/Department.java rename to testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Department.java diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Employee.java b/testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Employee.java similarity index 100% rename from easy-random/src/main/java/org/baeldung/easy/random/model/Employee.java rename to testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Employee.java diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Grade.java b/testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Grade.java similarity index 100% rename from easy-random/src/main/java/org/baeldung/easy/random/model/Grade.java rename to testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Grade.java diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Person.java b/testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Person.java similarity index 100% rename from easy-random/src/main/java/org/baeldung/easy/random/model/Person.java rename to testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/Person.java diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/YearQuarter.java b/testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/YearQuarter.java similarity index 100% rename from easy-random/src/main/java/org/baeldung/easy/random/model/YearQuarter.java rename to testing-modules/easy-random/src/main/java/org/baeldung/easy/random/model/YearQuarter.java diff --git a/easy-random/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java b/testing-modules/easy-random/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java similarity index 100% rename from easy-random/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java rename to testing-modules/easy-random/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java diff --git a/easy-random/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java b/testing-modules/easy-random/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java similarity index 100% rename from easy-random/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java rename to testing-modules/easy-random/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index bc6e23a6b7..3a1c3f3bf4 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -14,6 +14,7 @@ + easy-random gatling groovy-spock junit-5 From f021581f3c78664798d390d3f9c411ca0402e7b0 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 13 Jul 2019 12:27:26 +0530 Subject: [PATCH 49/74] [BAEL-12826] - Let's break the junit-5 module --- testing-modules/junit-5-basics/README.md | 8 +++++++- .../src/main/java/com/baeldung/junit5/Greetings.java | 0 .../main/java/com/baeldung/junit5/bean/NumbersBean.java | 0 .../src/test/java/com/baeldung/ExceptionUnitTest.java | 0 .../src/test/java/com/baeldung/FirstUnitTest.java | 0 .../src/test/java/com/baeldung/GreetingsUnitTest.java | 0 .../test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java | 0 .../src/test/java/com/baeldung/LiveTest.java | 0 .../baeldung/exception/ExceptionAssertionUnitTest.java | 0 .../baeldung/junit5/bean/test/NumbersBeanUnitTest.java | 0 .../baeldung/junit5/spring/GreetingsSpringUnitTest.java | 0 .../baeldung/junit5/spring/SpringTestConfiguration.java | 0 .../migration/junit4/AnnotationTestExampleUnitTest.java | 0 .../migration/junit4/AssertionsExampleUnitTest.java | 0 .../junit4/BeforeAndAfterAnnotationsUnitTest.java | 0 .../BeforeClassAndAfterClassAnnotationsUnitTest.java | 0 .../migration/junit4/ExceptionAssertionUnitTest.java | 0 .../baeldung/migration/junit4/RuleExampleUnitTest.java | 0 .../baeldung/migration/junit4/categories/Annotations.java | 0 .../migration/junit4/categories/JUnit4UnitTest.java | 0 .../migration/junit4/rules/TraceUnitTestRule.java | 0 .../migration/junit5/AnnotationTestExampleUnitTest.java | 0 .../migration/junit5/AssertionsExampleUnitTest.java | 0 .../com/baeldung/migration/junit5/AssumptionUnitTest.java | 0 .../junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java | 0 .../junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java | 0 .../baeldung/migration/junit5/RuleExampleUnitTest.java | 0 .../migration/junit5/extensions/TraceUnitExtension.java | 0 .../resourcedirectory/ReadResourceDirectoryUnitTest.java | 6 +++--- .../src/test/java/com/baeldung/suites/AllUnitTest.java | 0 testing-modules/junit-5/README.md | 7 ------- 31 files changed, 10 insertions(+), 11 deletions(-) rename testing-modules/{junit-5 => junit-5-basics}/src/main/java/com/baeldung/junit5/Greetings.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/main/java/com/baeldung/junit5/bean/NumbersBean.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/ExceptionUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/FirstUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/GreetingsUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/LiveTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/exception/ExceptionAssertionUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/junit5/spring/GreetingsSpringUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/AssertionsExampleUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/ExceptionAssertionUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/categories/JUnit4UnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java (100%) rename testing-modules/{junit-5 => junit-5-basics}/src/test/java/com/baeldung/suites/AllUnitTest.java (100%) diff --git a/testing-modules/junit-5-basics/README.md b/testing-modules/junit-5-basics/README.md index c09c030780..2c924a15a7 100644 --- a/testing-modules/junit-5-basics/README.md +++ b/testing-modules/junit-5-basics/README.md @@ -1,5 +1,11 @@ ### Relevant Articles: - +- [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview) +- [A Guide to JUnit 5](http://www.baeldung.com/junit-5) +- [JUnit5 @RunWith](http://www.baeldung.com/junit-5-runwith) - [Get the Path of the /src/test/resources Directory in JUnit](https://www.baeldung.com/junit-src-test-resources-directory-path) - [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junit-filtering-tests) - [JUnit 5 Temporary Directory Support](https://www.baeldung.com/junit-5-temporary-directory) +- [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall) +- [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation) +- [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration) +- [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception) \ No newline at end of file diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/Greetings.java b/testing-modules/junit-5-basics/src/main/java/com/baeldung/junit5/Greetings.java similarity index 100% rename from testing-modules/junit-5/src/main/java/com/baeldung/junit5/Greetings.java rename to testing-modules/junit-5-basics/src/main/java/com/baeldung/junit5/Greetings.java diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/bean/NumbersBean.java b/testing-modules/junit-5-basics/src/main/java/com/baeldung/junit5/bean/NumbersBean.java similarity index 100% rename from testing-modules/junit-5/src/main/java/com/baeldung/junit5/bean/NumbersBean.java rename to testing-modules/junit-5-basics/src/main/java/com/baeldung/junit5/bean/NumbersBean.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/ExceptionUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/ExceptionUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/ExceptionUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/ExceptionUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/FirstUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/FirstUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/FirstUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/FirstUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/GreetingsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/GreetingsUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/GreetingsUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/GreetingsUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/LiveTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/LiveTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/LiveTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/LiveTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/exception/ExceptionAssertionUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/exception/ExceptionAssertionUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/exception/ExceptionAssertionUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/exception/ExceptionAssertionUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/junit5/spring/GreetingsSpringUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/junit5/spring/GreetingsSpringUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AssertionsExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/AssertionsExampleUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AssertionsExampleUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/AssertionsExampleUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeAndAfterAnnotationsUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/BeforeClassAndAfterClassAnnotationsUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/ExceptionAssertionUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/ExceptionAssertionUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/ExceptionAssertionUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/ExceptionAssertionUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/RuleExampleUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/JUnit4UnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/categories/JUnit4UnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/JUnit4UnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/categories/JUnit4UnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java index 20fa372abd..eb8cab2462 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/resourcedirectory/ReadResourceDirectoryUnitTest.java @@ -17,7 +17,7 @@ public class ReadResourceDirectoryUnitTest { String absolutePath = file.getAbsolutePath(); System.out.println(absolutePath); - Assert.assertTrue(absolutePath.endsWith("src/test/resources")); + Assert.assertTrue(absolutePath.endsWith("src" + File.separator + "test" + File.separator + "resources")); } @Test @@ -27,7 +27,7 @@ public class ReadResourceDirectoryUnitTest { String absolutePath = resourceDirectory.toFile().getAbsolutePath(); System.out.println(absolutePath); - Assert.assertTrue(absolutePath.endsWith("src/test/resources")); + Assert.assertTrue(absolutePath.endsWith("src" + File.separator + "test" + File.separator + "resources")); } @Test @@ -39,7 +39,7 @@ public class ReadResourceDirectoryUnitTest { String absolutePath = file.getAbsolutePath(); System.out.println(absolutePath); - Assert.assertTrue(absolutePath.endsWith("/example_resource.txt")); + Assert.assertTrue(absolutePath.endsWith(File.separator + "example_resource.txt")); } } diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/suites/AllUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/suites/AllUnitTest.java similarity index 100% rename from testing-modules/junit-5/src/test/java/com/baeldung/suites/AllUnitTest.java rename to testing-modules/junit-5-basics/src/test/java/com/baeldung/suites/AllUnitTest.java diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md index 47db6587b4..d543b9b09b 100644 --- a/testing-modules/junit-5/README.md +++ b/testing-modules/junit-5/README.md @@ -1,16 +1,9 @@ ### Relevant Articles: -- [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview) -- [A Guide to JUnit 5](http://www.baeldung.com/junit-5) - [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test) - [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) - [A Guide to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) - [Inject Parameters into JUnit Jupiter Unit Tests](http://www.baeldung.com/junit-5-parameters) - [Mockito and JUnit 5 – Using ExtendWith](http://www.baeldung.com/mockito-junit-5-extension) -- [JUnit5 @RunWith](http://www.baeldung.com/junit-5-runwith) -- [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation) -- [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception) -- [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall) -- [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration) - [JUnit5 Programmatic Extension Registration with @RegisterExtension](http://www.baeldung.com/junit-5-registerextension-annotation) - [The Order of Tests in JUnit](http://www.baeldung.com/junit-5-test-order) - [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java) From 8a9f399c96d3c58990331728e516b57d9df91d51 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 13 Jul 2019 11:31:47 +0300 Subject: [PATCH 50/74] Update README.md --- persistence-modules/spring-boot-persistence-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-boot-persistence-mongodb/README.md b/persistence-modules/spring-boot-persistence-mongodb/README.md index 40f9f40749..f277ef66ca 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb/README.md @@ -2,3 +2,4 @@ - [Auto-Generated Field for MongoDB using Spring Boot](https://www.baeldung.com/spring-boot-mongodb-auto-generated-field) - [Spring Boot Integration Testing with Embedded MongoDB](http://www.baeldung.com/spring-boot-embedded-mongodb) +- [Upload and Retrieve Files Using MongoDB and Spring Boot](https://www.baeldung.com/spring-boot-mongodb-upload-file) From 328a0d1e47ab12165122831a7627549b58ae4b28 Mon Sep 17 00:00:00 2001 From: Alexander Molochko Date: Sat, 13 Jul 2019 12:31:50 +0300 Subject: [PATCH 51/74] BAEL-2378 Non-blocking Spring Boot with Kotlin Coroutines (#6966) --- pom.xml | 1647 +++++++++-------- spring-boot-kotlin/README.md | 2 + spring-boot-kotlin/pom.xml | 166 ++ .../SpringApplication.kt | 11 + .../config/DatastoreConfig.kt | 32 + .../config/RouterConfiguration.kt | 19 + .../config/WebClientConfiguration.kt | 12 + .../controller/ProductController.kt | 49 + .../controller/ProductControllerCoroutines.kt | 49 + .../controller/ProductStockView.kt | 15 + .../handlers/ProductsHandler.kt | 49 + .../nonblockingcoroutines/model/Product.kt | 7 + .../repository/ProductRepository.kt | 34 + .../repository/ProductRepositoryCoroutines.kt | 40 + .../src/main/resources/application.properties | 8 + .../src/main/resources/logback.xml | 13 + .../ProductHandlerTest.kt | 58 + 17 files changed, 1388 insertions(+), 823 deletions(-) create mode 100644 spring-boot-kotlin/README.md create mode 100644 spring-boot-kotlin/pom.xml create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/SpringApplication.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/DatastoreConfig.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/RouterConfiguration.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/WebClientConfiguration.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductController.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductControllerCoroutines.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductStockView.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/handlers/ProductsHandler.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/model/Product.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepository.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepositoryCoroutines.kt create mode 100644 spring-boot-kotlin/src/main/resources/application.properties create mode 100644 spring-boot-kotlin/src/main/resources/logback.xml create mode 100644 spring-boot-kotlin/src/test/kotlin/com/baeldung/nonblockingcoroutines/ProductHandlerTest.kt diff --git a/pom.xml b/pom.xml index d27c4d8a3d..f40659bc16 100644 --- a/pom.xml +++ b/pom.xml @@ -1,18 +1,18 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung parent-modules 1.0.0-SNAPSHOT - parent-modules + parent-modules pom - - quarkus - + + quarkus + @@ -57,11 +57,11 @@ test - org.junit.jupiter - junit-jupiter-api + org.junit.jupiter + junit-jupiter-api ${junit-jupiter.version} test - + org.hamcrest hamcrest-core @@ -123,22 +123,22 @@ - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform.version} - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - - + + org.junit.platform + junit-platform-surefire-provider + ${junit-platform.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + + + org.junit.vintage + junit-vintage-engine + ${junit-jupiter.version} + + org.apache.maven.plugins @@ -328,62 +328,62 @@ parent-boot-1 - parent-boot-2 - parent-spring-4 - parent-spring-5 - parent-java - parent-kotlin - - akka-streams - algorithms-genetic - algorithms-miscellaneous-1 - algorithms-miscellaneous-2 - algorithms-miscellaneous-3 - algorithms-sorting - animal-sniffer-mvn-plugin - annotations - antlr - apache-avro - apache-bval - apache-curator - apache-cxf - apache-fop - apache-geode - apache-meecrowave - apache-opennlp - apache-poi - apache-pulsar - apache-shiro - apache-solrj - apache-spark - apache-thrift - apache-tika - apache-velocity - apache-zookeeper - asciidoctor - asm - atomix - autovalue - aws - aws-lambda - axon - azure + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin + + akka-streams + algorithms-genetic + algorithms-miscellaneous-1 + algorithms-miscellaneous-2 + algorithms-miscellaneous-3 + algorithms-sorting + animal-sniffer-mvn-plugin + annotations + antlr + apache-avro + apache-bval + apache-curator + apache-cxf + apache-fop + apache-geode + apache-meecrowave + apache-opennlp + apache-poi + apache-pulsar + apache-shiro + apache-solrj + apache-spark + apache-thrift + apache-tika + apache-velocity + apache-zookeeper + asciidoctor + asm + atomix + autovalue + aws + aws-lambda + axon + azure - blade + blade - bootique + bootique - cas - cdi - checker-plugin - core-groovy - core-groovy-2 - core-groovy-collections - - - - core-java-modules/core-java-8 - core-java-modules/core-java-8-2 + cas + cdi + checker-plugin + core-groovy + core-groovy-2 + core-groovy-collections + + + + core-java-modules/core-java-8 + core-java-modules/core-java-8-2 core-java-modules/core-java-lambdas @@ -475,84 +475,84 @@ jaxb - jee-7-security - jersey - JGit - jgroups - jhipster - jhipster-5 - jib - jjwt - jmeter - jmh - jni - jooby - jsf - json - json-path - jsoup - jta + jee-7-security + jersey + JGit + jgroups + jhipster + jhipster-5 + jib + jjwt + jmeter + jmh + jni + jooby + jsf + json + json-path + jsoup + jta - - kotlin-libraries - kotlin-libraries-2 + + kotlin-libraries + kotlin-libraries-2 - - libraries - libraries-2 - libraries-data - libraries-apache-commons - libraries-primitive - libraries-security - libraries-server - libraries-http - linkrest - logging-modules - lombok - lucene + + libraries + libraries-2 + libraries-data + libraries-apache-commons + libraries-primitive + libraries-security + libraries-server + libraries-http + linkrest + logging-modules + lombok + lucene - mapstruct - maven - maven-archetype - - maven-polyglot/maven-polyglot-json-extension - - mesos-marathon - metrics - - microprofile - msf4j - - mustache - mybatis + mapstruct + maven + maven-archetype + + maven-polyglot/maven-polyglot-json-extension + + mesos-marathon + metrics + + microprofile + msf4j + + mustache + mybatis - optaplanner - orika - osgi + optaplanner + orika + osgi - patterns - pdf - performance-tests - - protobuffer + patterns + pdf + performance-tests + + protobuffer - persistence-modules - quarkus + persistence-modules + quarkus - rabbitmq - - ratpack - reactor-core - rest-with-spark-java - resteasy - restx - - rule-engines + rabbitmq + + ratpack + reactor-core + rest-with-spark-java + resteasy + restx + + rule-engines rsocket - rxjava - rxjava-2 - software-security/sql-injection-samples + rxjava + rxjava-2 + software-security/sql-injection-samples tensorflow-java spring-boot-flowable @@ -563,239 +563,240 @@ - - default-second - - + + default-second + + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/*JdbcTest.java - **/*LiveTest.java - - - + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/*JdbcTest.java + **/*LiveTest.java + + + - - + + - - parent-boot-1 - parent-boot-2 - parent-spring-4 - parent-spring-5 - parent-java - parent-kotlin + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin - saas - spark-java + saas + spark-java - spring-4 + spring-4 - spring-5 - spring-5-webflux - spring-5-data-reactive - spring-5-mvc - spring-5-reactive - spring-5-reactive-client - spring-5-reactive-oauth - spring-5-reactive-security - spring-5-security - spring-5-security-oauth - spring-5-security-cognito + spring-5 + spring-5-webflux + spring-5-data-reactive + spring-5-mvc + spring-5-reactive + spring-5-reactive-client + spring-5-reactive-oauth + spring-5-reactive-security + spring-5-security + spring-5-security-oauth + spring-5-security-cognito - spring-activiti - spring-akka - spring-all - spring-amqp - spring-amqp-simple - spring-aop - spring-apache-camel - spring-batch - spring-bom + spring-activiti + spring-akka + spring-all + spring-amqp + spring-amqp-simple + spring-aop + spring-apache-camel + spring-batch + spring-bom - spring-boot - spring-boot-admin - spring-boot-angular - spring-boot-angular-ecommerce - spring-boot-autoconfiguration - spring-boot-bootstrap - spring-boot-camel - - spring-boot-client + spring-boot + spring-boot-admin + spring-boot-angular + spring-boot-angular-ecommerce + spring-boot-autoconfiguration + spring-boot-bootstrap + spring-boot-camel + + spring-boot-client - spring-boot-crud - spring-boot-ctx-fluent - spring-boot-custom-starter - spring-boot-disable-console-logging - - spring-boot-jasypt - spring-boot-keycloak - spring-boot-logging-log4j2 - spring-boot-mvc - spring-boot-mvc-birt - spring-boot-ops - spring-boot-ops-2 - spring-boot-rest - spring-boot-data - spring-boot-parent - spring-boot-property-exp - spring-boot-security - spring-boot-testing - spring-boot-vue - spring-boot-libraries + spring-boot-crud + spring-boot-ctx-fluent + spring-boot-custom-starter + spring-boot-disable-console-logging + + spring-boot-jasypt + spring-boot-keycloak + spring-boot-kotlin + spring-boot-logging-log4j2 + spring-boot-mvc + spring-boot-mvc-birt + spring-boot-ops + spring-boot-ops-2 + spring-boot-rest + spring-boot-data + spring-boot-parent + spring-boot-property-exp + spring-boot-security + spring-boot-testing + spring-boot-vue + spring-boot-libraries - spring-cloud - spring-cloud-bus - - spring-cloud-data-flow + spring-cloud + spring-cloud-bus + + spring-cloud-data-flow - spring-core - spring-core-2 - spring-cucumber + spring-core + spring-core-2 + spring-cucumber - spring-data-rest - spring-data-rest-querydsl - spring-dispatcher-servlet - spring-drools + spring-data-rest + spring-data-rest-querydsl + spring-dispatcher-servlet + spring-drools - spring-ehcache - spring-ejb - spring-exceptions + spring-ehcache + spring-ejb + spring-exceptions - spring-freemarker + spring-freemarker - spring-groovy + spring-groovy - spring-integration + spring-integration - spring-jenkins-pipeline - spring-jersey - spring-jinq - spring-jms - spring-jooq + spring-jenkins-pipeline + spring-jersey + spring-jinq + spring-jms + spring-jooq - spring-kafka - spring-katharsis + spring-kafka + spring-katharsis - spring-ldap + spring-ldap - spring-mobile - spring-mockito - spring-mvc-forms-jsp - spring-mvc-forms-thymeleaf - spring-mvc-java - spring-mvc-kotlin - spring-mvc-simple - spring-mvc-simple-2 - spring-mvc-velocity - spring-mvc-webflow - spring-mvc-xml + spring-mobile + spring-mockito + spring-mvc-forms-jsp + spring-mvc-forms-thymeleaf + spring-mvc-java + spring-mvc-kotlin + spring-mvc-simple + spring-mvc-simple-2 + spring-mvc-velocity + spring-mvc-webflow + spring-mvc-xml - spring-protobuf - + spring-protobuf + - spring-quartz + spring-quartz - spring-reactive-kotlin - spring-reactor - spring-remoting - spring-rest - spring-rest-angular - spring-rest-full - spring-rest-hal-browser - spring-rest-query-language - spring-rest-shell - spring-rest-simple - spring-resttemplate - spring-roo - spring-security-acl - spring-security-angular/server - spring-security-cache-control + spring-reactive-kotlin + spring-reactor + spring-remoting + spring-rest + spring-rest-angular + spring-rest-full + spring-rest-hal-browser + spring-rest-query-language + spring-rest-shell + spring-rest-simple + spring-resttemplate + spring-roo + spring-security-acl + spring-security-angular/server + spring-security-cache-control - spring-security-client + spring-security-client - spring-security-core - spring-security-mvc-boot - spring-security-mvc-custom - spring-security-mvc-digest-auth + spring-security-core + spring-security-mvc-boot + spring-security-mvc-custom + spring-security-mvc-digest-auth spring-security-mvc-jsonview - spring-security-mvc-ldap - spring-security-mvc-login - spring-security-mvc-persisted-remember-me - spring-security-mvc-session - spring-security-mvc-socket - spring-security-openid - - spring-security-rest - spring-security-rest-basic-auth - spring-security-rest-custom - spring-security-sso - spring-security-stormpath - spring-security-thymeleaf - spring-security-x509 - spring-session - spring-sleuth - spring-soap - spring-social-login - spring-spel - spring-state-machine - spring-static-resources - spring-swagger-codegen + spring-security-mvc-ldap + spring-security-mvc-login + spring-security-mvc-persisted-remember-me + spring-security-mvc-session + spring-security-mvc-socket + spring-security-openid + + spring-security-rest + spring-security-rest-basic-auth + spring-security-rest-custom + spring-security-sso + spring-security-stormpath + spring-security-thymeleaf + spring-security-x509 + spring-session + spring-sleuth + spring-soap + spring-social-login + spring-spel + spring-state-machine + spring-static-resources + spring-swagger-codegen - spring-thymeleaf + spring-thymeleaf - spring-userservice + spring-userservice - spring-vault - spring-vertx + spring-vault + spring-vertx - spring-webflux-amqp + spring-webflux-amqp - spring-zuul + spring-zuul - static-analysis - stripe - structurizr - struts-2 + static-analysis + stripe + structurizr + struts-2 - testing-modules + testing-modules - twilio - Twitter4J + twilio + Twitter4J - undertow + undertow - vavr - vertx - vertx-and-rxjava - video-tutorials - vraptor + vavr + vertx + vertx-and-rxjava + video-tutorials + vraptor - wicket + wicket - xml - xmlunit-2 - xstream + xml + xmlunit-2 + xstream tensorflow-java spring-boot-flowable spring-security-kerberos morphia - + - + spring-context @@ -840,7 +841,7 @@ spring-boot-camel spring-boot-client spring-boot-custom-starter - greeter-spring-boot-autoconfigure + greeter-spring-boot-autoconfigure greeter-spring-boot-sample-app persistence-modules/spring-boot-h2/spring-boot-h2-database spring-boot-jasypt @@ -943,571 +944,571 @@ - - default-heavy - - + + default-heavy + + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/*JdbcTest.java - **/*LiveTest.java - - - + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/*JdbcTest.java + **/*LiveTest.java + + + - - + + - - parent-boot-1 - parent-boot-2 - parent-spring-4 - parent-spring-5 - parent-java - parent-kotlin + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin - core-java-modules/core-java-concurrency-advanced - core-kotlin - core-kotlin-2 - core-kotlin-io + core-java-modules/core-java-concurrency-advanced + core-kotlin + core-kotlin-2 + core-kotlin-io - jenkins/hello-world - jws + jenkins/hello-world + jws - libraries + libraries - persistence-modules/hibernate5 - persistence-modules/hibernate-mapping - persistence-modules/java-jpa - persistence-modules/java-mongodb - persistence-modules/jnosql + persistence-modules/hibernate5 + persistence-modules/hibernate-mapping + persistence-modules/java-jpa + persistence-modules/java-mongodb + persistence-modules/jnosql - vaadin - - + vaadin + + - - integration-lite-first + + integration-lite-first - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*ManualTest.java - **/*LiveTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*ManualTest.java + **/*LiveTest.java + + + **/*IntegrationTest.java + **/*IntTest.java + + + + + - - parent-boot-1 - parent-boot-2 - parent-spring-4 - parent-spring-5 - parent-java - parent-kotlin - - akka-streams - algorithms-genetic - algorithms-miscellaneous-1 - algorithms-miscellaneous-2 - algorithms-miscellaneous-3 - algorithms-sorting - animal-sniffer-mvn-plugin - annotations - antlr - apache-avro - apache-bval - apache-curator - apache-cxf - apache-fop - apache-geode - apache-meecrowave - apache-opennlp - apache-poi - apache-pulsar - apache-shiro - apache-solrj - apache-spark - apache-thrift - apache-tika - apache-velocity - apache-zookeeper - asciidoctor - asm - atomix - autovalue - aws - aws-lambda - axon - azure + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin + + akka-streams + algorithms-genetic + algorithms-miscellaneous-1 + algorithms-miscellaneous-2 + algorithms-miscellaneous-3 + algorithms-sorting + animal-sniffer-mvn-plugin + annotations + antlr + apache-avro + apache-bval + apache-curator + apache-cxf + apache-fop + apache-geode + apache-meecrowave + apache-opennlp + apache-poi + apache-pulsar + apache-shiro + apache-solrj + apache-spark + apache-thrift + apache-tika + apache-velocity + apache-zookeeper + asciidoctor + asm + atomix + autovalue + aws + aws-lambda + axon + azure - bootique + bootique - cas - cdi - checker-plugin - core-groovy - core-groovy-2 - core-groovy-collections - - - core-java-modules/core-java-8 - core-java-modules/core-java-8-2 - - - core-java-modules/core-java-arrays - core-java-modules/core-java-collections - core-java-modules/core-java-collections-list - core-java-modules/core-java-collections-list-2 - core-java-modules/core-java-collections-array-list - core-java-modules/core-java-collections-set - core-java-modules/core-java-concurrency-basic - core-java-modules/core-java-concurrency-collections - core-java-modules/core-java-io - core-java-modules/core-java-nio - core-java-modules/core-java-security - core-java-modules/core-java-lang-syntax - core-java-modules/core-java-lang - core-java-modules/core-java-lang-oop - core-java-modules/core-java-lang-oop-2 - core-java-modules - core-java-modules/core-java-networking - core-java-modules/core-java-perf - core-java-modules/core-java-sun - core-scala - couchbase - custom-pmd + cas + cdi + checker-plugin + core-groovy + core-groovy-2 + core-groovy-collections + + + core-java-modules/core-java-8 + core-java-modules/core-java-8-2 + + + core-java-modules/core-java-arrays + core-java-modules/core-java-collections + core-java-modules/core-java-collections-list + core-java-modules/core-java-collections-list-2 + core-java-modules/core-java-collections-array-list + core-java-modules/core-java-collections-set + core-java-modules/core-java-concurrency-basic + core-java-modules/core-java-concurrency-collections + core-java-modules/core-java-io + core-java-modules/core-java-nio + core-java-modules/core-java-security + core-java-modules/core-java-lang-syntax + core-java-modules/core-java-lang + core-java-modules/core-java-lang-oop + core-java-modules/core-java-lang-oop-2 + core-java-modules + core-java-modules/core-java-networking + core-java-modules/core-java-perf + core-java-modules/core-java-sun + core-scala + couchbase + custom-pmd - dagger - data-structures - ddd - deeplearning4j - disruptor - dozer - drools - dubbo + dagger + data-structures + ddd + deeplearning4j + disruptor + dozer + drools + dubbo - ethereum + ethereum - feign - flyway-cdi-extension + feign + flyway-cdi-extension - geotools - google-cloud - google-web-toolkit - - - graphql/graphql-java - grpc - gson - guava - guava-collections - guava-modules - - guice + geotools + google-cloud + google-web-toolkit + + + graphql/graphql-java + grpc + gson + guava + guava-collections + guava-modules + + guice - hazelcast - helidon - httpclient - httpclient-simple - hystrix + hazelcast + helidon + httpclient + httpclient-simple + hystrix - image-processing - immutables + image-processing + immutables - jackson - jackson-2 - jackson-simple - java-collections-conversions - java-collections-maps - java-collections-maps-2 - - java-ee-8-security-api - java-lite - java-numbers - java-rmi - java-spi - java-streams - - java-strings - java-strings-2 - java-vavr-stream - java-websocket - javafx - javax-servlets - javaxval - jaxb - + java-ee-8-security-api + java-lite + java-numbers + java-rmi + java-spi + java-streams + + java-strings + java-strings-2 + java-vavr-stream + java-websocket + javafx + javax-servlets + javaxval + jaxb + - jee-7-security - jersey - JGit - jgroups - jhipster - jhipster-5 - jib - jjwt - jmeter - jmh - jni - jooby - jsf - json - json-path - jsoup - jta + jee-7-security + jersey + JGit + jgroups + jhipster + jhipster-5 + jib + jjwt + jmeter + jmh + jni + jooby + jsf + json + json-path + jsoup + jta - - kotlin-libraries + + kotlin-libraries - - libraries - libraries-data - libraries-apache-commons - libraries-security - libraries-server - libraries-http - linkrest - logging-modules - lombok - lucene + + libraries + libraries-data + libraries-apache-commons + libraries-security + libraries-server + libraries-http + linkrest + logging-modules + lombok + lucene - mapstruct - maven - - maven-archetype - - maven-polyglot/maven-polyglot-json-extension - - mesos-marathon - metrics - - microprofile - msf4j - - mustache - mybatis + mapstruct + maven + + maven-archetype + + maven-polyglot/maven-polyglot-json-extension + + mesos-marathon + metrics + + microprofile + msf4j + + mustache + mybatis - optaplanner - orika - osgi + optaplanner + orika + osgi - patterns - pdf - performance-tests - - protobuffer + patterns + pdf + performance-tests + + protobuffer - persistence-modules + persistence-modules - rabbitmq - - ratpack - reactor-core - rest-with-spark-java - resteasy - restx - - rule-engines - rsocket - rxjava - rxjava-2 + rabbitmq + + ratpack + reactor-core + rest-with-spark-java + resteasy + restx + + rule-engines + rsocket + rxjava + rxjava-2 - + - + - - integration-lite-second + + integration-lite-second - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*ManualTest.java - **/*LiveTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*ManualTest.java + **/*LiveTest.java + + + **/*IntegrationTest.java + **/*IntTest.java + + + + + - - parent-boot-1 - parent-boot-2 - parent-spring-4 - parent-spring-5 - parent-java - parent-kotlin + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin - saas - spark-java + saas + spark-java - spring-4 + spring-4 - spring-5 - spring-5-data-reactive - spring-5-mvc - spring-5-reactive - spring-5-reactive-client - spring-5-reactive-oauth - spring-5-reactive-security - spring-5-security - spring-5-security-oauth - spring-5-security-cognito - spring-activiti - spring-akka - spring-all - spring-amqp - spring-amqp-simple - spring-aop - spring-apache-camel - spring-batch - spring-bom + spring-5 + spring-5-data-reactive + spring-5-mvc + spring-5-reactive + spring-5-reactive-client + spring-5-reactive-oauth + spring-5-reactive-security + spring-5-security + spring-5-security-oauth + spring-5-security-cognito + spring-activiti + spring-akka + spring-all + spring-amqp + spring-amqp-simple + spring-aop + spring-apache-camel + spring-batch + spring-bom - spring-boot - spring-boot-admin - spring-boot-angular - spring-boot-angular-ecommerce - spring-boot-autoconfiguration - spring-boot-bootstrap - spring-boot-camel - - spring-boot-client - spring-boot-crud - spring-boot-ctx-fluent - spring-boot-custom-starter - spring-boot-disable-console-logging - - spring-boot-jasypt - spring-boot-keycloak - spring-boot-logging-log4j2 - spring-boot-mvc - spring-boot-mvc-birt - spring-boot-ops - spring-boot-ops-2 - spring-boot-rest - spring-boot-data - spring-boot-parent - spring-boot-property-exp - spring-boot-security - spring-boot-vue + spring-boot + spring-boot-admin + spring-boot-angular + spring-boot-angular-ecommerce + spring-boot-autoconfiguration + spring-boot-bootstrap + spring-boot-camel + + spring-boot-client + spring-boot-crud + spring-boot-ctx-fluent + spring-boot-custom-starter + spring-boot-disable-console-logging + + spring-boot-jasypt + spring-boot-keycloak + spring-boot-logging-log4j2 + spring-boot-mvc + spring-boot-mvc-birt + spring-boot-ops + spring-boot-ops-2 + spring-boot-rest + spring-boot-data + spring-boot-parent + spring-boot-property-exp + spring-boot-security + spring-boot-vue - spring-cloud - spring-cloud-bus - - spring-cloud-data-flow + spring-cloud + spring-cloud-bus + + spring-cloud-data-flow - spring-core - spring-core-2 - spring-cucumber + spring-core + spring-core-2 + spring-cucumber - spring-data-rest - spring-data-rest-querydsl - spring-dispatcher-servlet - spring-drools + spring-data-rest + spring-data-rest-querydsl + spring-dispatcher-servlet + spring-drools spring-ehcache - spring-ejb - spring-exceptions + spring-ejb + spring-exceptions - spring-freemarker + spring-freemarker - spring-groovy + spring-groovy - spring-integration + spring-integration - spring-jenkins-pipeline - spring-jersey - spring-jinq - spring-jms - spring-jooq + spring-jenkins-pipeline + spring-jersey + spring-jinq + spring-jms + spring-jooq - spring-kafka - spring-katharsis + spring-kafka + spring-katharsis - spring-ldap + spring-ldap - spring-mobile - spring-mockito - spring-mvc-forms-jsp - spring-mvc-forms-thymeleaf - spring-mvc-java - spring-mvc-kotlin - spring-mvc-simple - spring-mvc-simple-2 - spring-mvc-velocity - spring-mvc-webflow - spring-mvc-xml + spring-mobile + spring-mockito + spring-mvc-forms-jsp + spring-mvc-forms-thymeleaf + spring-mvc-java + spring-mvc-kotlin + spring-mvc-simple + spring-mvc-simple-2 + spring-mvc-velocity + spring-mvc-webflow + spring-mvc-xml - spring-protobuf - + spring-protobuf + - spring-quartz + spring-quartz - spring-reactive-kotlin - spring-reactor - spring-remoting - spring-rest - spring-rest-angular - spring-rest-full - spring-rest-hal-browser - spring-rest-query-language - spring-rest-shell - spring-rest-simple - spring-resttemplate - spring-roo + spring-reactive-kotlin + spring-reactor + spring-remoting + spring-rest + spring-rest-angular + spring-rest-full + spring-rest-hal-browser + spring-rest-query-language + spring-rest-shell + spring-rest-simple + spring-resttemplate + spring-roo - spring-security-acl - spring-security-angular/server - spring-security-cache-control + spring-security-acl + spring-security-angular/server + spring-security-cache-control - spring-security-client + spring-security-client - spring-security-core - spring-security-mvc-boot - spring-security-mvc-custom - spring-security-mvc-digest-auth - spring-security-mvc-ldap - spring-security-mvc-login - spring-security-mvc-persisted-remember-me - spring-security-mvc-session - spring-security-mvc-socket - spring-security-openid - - spring-security-rest - spring-security-rest-basic-auth - spring-security-rest-custom - spring-security-sso - spring-security-stormpath - spring-security-thymeleaf - spring-security-x509 - spring-session - spring-sleuth - spring-soap - spring-social-login - spring-spel - spring-state-machine - spring-static-resources - spring-swagger-codegen + spring-security-core + spring-security-mvc-boot + spring-security-mvc-custom + spring-security-mvc-digest-auth + spring-security-mvc-ldap + spring-security-mvc-login + spring-security-mvc-persisted-remember-me + spring-security-mvc-session + spring-security-mvc-socket + spring-security-openid + + spring-security-rest + spring-security-rest-basic-auth + spring-security-rest-custom + spring-security-sso + spring-security-stormpath + spring-security-thymeleaf + spring-security-x509 + spring-session + spring-sleuth + spring-soap + spring-social-login + spring-spel + spring-state-machine + spring-static-resources + spring-swagger-codegen - spring-thymeleaf + spring-thymeleaf - spring-userservice + spring-userservice - spring-vault - spring-vertx + spring-vault + spring-vertx - spring-webflux-amqp + spring-webflux-amqp - spring-zuul + spring-zuul - static-analysis - stripe - structurizr - struts-2 + static-analysis + stripe + structurizr + struts-2 - testing-modules + testing-modules - twilio - Twitter4J + twilio + Twitter4J - undertow + undertow - vavr - vertx - vertx-and-rxjava - video-tutorials - vraptor + vavr + vertx + vertx-and-rxjava + video-tutorials + vraptor - wicket + wicket - xml - xmlunit-2 - xstream + xml + xmlunit-2 + xstream - + - + - - integration-heavy + + integration-heavy - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*ManualTest.java - **/*LiveTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*ManualTest.java + **/*LiveTest.java + + + **/*IntegrationTest.java + **/*IntTest.java + + + + + - - parent-boot-1 - parent-boot-2 - parent-spring-4 - parent-spring-5 - parent-java - parent-kotlin + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin - core-java-modules/core-java - core-java-modules/core-java-concurrency-advanced - core-kotlin - core-kotlin-2 + core-java-modules/core-java + core-java-modules/core-java-concurrency-advanced + core-kotlin + core-kotlin-2 - jenkins/hello-world - jws + jenkins/hello-world + jws - libraries + libraries - persistence-modules/hibernate5 - persistence-modules/java-jpa - persistence-modules/java-mongodb - persistence-modules/jnosql + persistence-modules/hibernate5 + persistence-modules/java-jpa + persistence-modules/java-mongodb + persistence-modules/jnosql - vaadin - + vaadin + - + @@ -1541,7 +1542,7 @@ 1.1.7 - + 2.21.0 3.7.0 1.6.0 diff --git a/spring-boot-kotlin/README.md b/spring-boot-kotlin/README.md new file mode 100644 index 0000000000..dc50c24aa0 --- /dev/null +++ b/spring-boot-kotlin/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Non-blocking Spring Boot with Kotlin Coroutines](http://www.baeldung.com/non-blocking-spring-boot-with-kotlin-coroutines) diff --git a/spring-boot-kotlin/pom.xml b/spring-boot-kotlin/pom.xml new file mode 100644 index 0000000000..25508c52b9 --- /dev/null +++ b/spring-boot-kotlin/pom.xml @@ -0,0 +1,166 @@ + + + 4.0.0 + spring-boot-kotlin + spring-boot-kotlin + jar + Demo project showing how to use non-blocking in Kotlin with Spring Boot + + + parent-kotlin + com.baeldung + 1.0.0-SNAPSHOT + ../parent-kotlin + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + + + org.jetbrains.kotlin + kotlin-reflect + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + + + org.jetbrains.kotlinx + kotlinx-coroutines-core + ${kotlinx-coroutines.version} + + + org.jetbrains.kotlinx + kotlinx-coroutines-reactor + ${kotlinx-coroutines.version} + + + org.springframework.boot + spring-boot-starter-webflux + ${spring-boot.version} + + + com.fasterxml.jackson.module + jackson-module-kotlin + + + org.springframework.data + spring-data-r2dbc + ${r2dbc.version} + + + io.r2dbc + r2dbc-h2 + ${h2-r2dbc.version} + + + io.r2dbc + r2dbc-spi + ${r2dbc-spi.version} + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + io.projectreactor + reactor-test + test + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + -Xjsr305=strict + + + spring + + + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + + + + + + 1.3.31 + 1.0.0.M1 + 1.0.0.M7 + 1.0.0.BUILD-SNAPSHOT + 1.2.1 + 2.2.0.M2 + + + diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/SpringApplication.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/SpringApplication.kt new file mode 100644 index 0000000000..23af4fe90b --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/SpringApplication.kt @@ -0,0 +1,11 @@ +package com.baeldung.nonblockingcoroutines + +import org.springframework.boot.SpringApplication.run +import org.springframework.boot.autoconfigure.SpringBootApplication + +@SpringBootApplication +class SpringApplication + +fun main(args: Array) { + run(SpringApplication::class.java, *args) +} diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/DatastoreConfig.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/DatastoreConfig.kt new file mode 100644 index 0000000000..52ef8a708b --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/DatastoreConfig.kt @@ -0,0 +1,32 @@ +package com.baeldung.nonblockingcoroutines.config + +import io.r2dbc.h2.H2ConnectionConfiguration +import io.r2dbc.h2.H2ConnectionFactory +import io.r2dbc.spi.ConnectionFactory +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration +import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories + +@Configuration +@EnableR2dbcRepositories +class DatastoreConfig : AbstractR2dbcConfiguration() { + @Value("\${spring.datasource.username}") + private val userName: String = "" + + @Value("\${spring.datasource.password}") + private val password: String = "" + + @Value("\${spring.datasource.dbname}") + private val dbName: String = "" + + @Bean + override fun connectionFactory(): ConnectionFactory { + return H2ConnectionFactory(H2ConnectionConfiguration.builder() + .inMemory(dbName) + .username(userName) + .password(password) + .build()) + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/RouterConfiguration.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/RouterConfiguration.kt new file mode 100644 index 0000000000..bda1d26278 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/RouterConfiguration.kt @@ -0,0 +1,19 @@ +package com.baeldung.nonblockingcoroutines.config + +import com.baeldung.nonblockingcoroutines.handlers.ProductsHandler +import kotlinx.coroutines.FlowPreview +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.web.reactive.function.server.coRouter + +@Configuration +class RouterConfiguration { + + @FlowPreview + @Bean + fun productRoutes(productsHandler: ProductsHandler) = coRouter { + GET("/", productsHandler::findAll) + GET("/{id}", productsHandler::findOne) + GET("/{id}/stock", productsHandler::findOneInStock) + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/WebClientConfiguration.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/WebClientConfiguration.kt new file mode 100644 index 0000000000..85938b8be2 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/config/WebClientConfiguration.kt @@ -0,0 +1,12 @@ +package com.baeldung.nonblockingcoroutines.config + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.web.reactive.function.client.WebClient + +@Configuration +class WebClientConfiguration { + + @Bean + fun webClient() = WebClient.builder().baseUrl("http://localhost:8080").build() +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductController.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductController.kt new file mode 100644 index 0000000000..91b091859a --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductController.kt @@ -0,0 +1,49 @@ +package com.baeldung.nonblockingcoroutines.controller + +import com.baeldung.nonblockingcoroutines.model.Product +import com.baeldung.nonblockingcoroutines.repository.ProductRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.reactive.function.client.WebClient +import org.springframework.web.reactive.function.client.bodyToMono +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono + +class ProductController { + @Autowired + lateinit var webClient: WebClient + @Autowired + lateinit var productRepository: ProductRepository + + @GetMapping("/{id}") + fun findOne(@PathVariable id: Int): Mono { + return productRepository + .getProductById(id) + } + + @GetMapping("/{id}/stock") + fun findOneInStock(@PathVariable id: Int): Mono { + val product = productRepository.getProductById(id) + + val stockQuantity = webClient.get() + .uri("/stock-service/product/$id/quantity") + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono() + return product.zipWith(stockQuantity) { productInStock, stockQty -> + ProductStockView(productInStock, stockQty) + } + } + + @GetMapping("/stock-service/product/{id}/quantity") + fun getStockQuantity(): Mono { + return Mono.just(2) + } + + @GetMapping("/") + fun findAll(): Flux { + return productRepository.getAllProducts() + } +} diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductControllerCoroutines.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductControllerCoroutines.kt new file mode 100644 index 0000000000..d70d352cda --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductControllerCoroutines.kt @@ -0,0 +1,49 @@ +package com.baeldung.nonblockingcoroutines.controller + +import com.baeldung.nonblockingcoroutines.model.Product +import com.baeldung.nonblockingcoroutines.repository.ProductRepositoryCoroutines +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async +import kotlinx.coroutines.flow.Flow +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.MediaType.APPLICATION_JSON +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.reactive.function.client.WebClient +import org.springframework.web.reactive.function.client.awaitBody +import org.springframework.web.reactive.function.client.awaitExchange + +class ProductControllerCoroutines { + @Autowired + lateinit var webClient: WebClient + + @Autowired + lateinit var productRepository: ProductRepositoryCoroutines + + @GetMapping("/{id}") + suspend fun findOne(@PathVariable id: Int): Product? { + return productRepository.getProductById(id) + } + + @GetMapping("/{id}/stock") + suspend fun findOneInStock(@PathVariable id: Int): ProductStockView { + val product: Deferred = GlobalScope.async { + productRepository.getProductById(id) + } + val quantity: Deferred = GlobalScope.async { + webClient.get() + .uri("/stock-service/product/$id/quantity") + .accept(APPLICATION_JSON) + .awaitExchange().awaitBody() + } + return ProductStockView(product.await()!!, quantity.await()) + } + + @FlowPreview + @GetMapping("/") + fun findAll(): Flow { + return productRepository.getAllProducts() + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductStockView.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductStockView.kt new file mode 100644 index 0000000000..44611fd1de --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/controller/ProductStockView.kt @@ -0,0 +1,15 @@ +package com.baeldung.nonblockingcoroutines.controller + +import com.baeldung.nonblockingcoroutines.model.Product + +class ProductStockView(product: Product, var stockQuantity: Int) { + var id: Int = 0 + var name: String = "" + var price: Float = 0.0f + + init { + this.id = product.id + this.name = product.name + this.price = product.price + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/handlers/ProductsHandler.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/handlers/ProductsHandler.kt new file mode 100644 index 0000000000..41c4510e0d --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/handlers/ProductsHandler.kt @@ -0,0 +1,49 @@ +package com.baeldung.nonblockingcoroutines.handlers + +import com.baeldung.nonblockingcoroutines.controller.ProductStockView +import com.baeldung.nonblockingcoroutines.model.Product +import com.baeldung.nonblockingcoroutines.repository.ProductRepositoryCoroutines +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.MediaType +import org.springframework.stereotype.Component +import org.springframework.web.reactive.function.client.WebClient +import org.springframework.web.reactive.function.client.awaitBody +import org.springframework.web.reactive.function.client.awaitExchange +import org.springframework.web.reactive.function.server.ServerRequest +import org.springframework.web.reactive.function.server.ServerResponse +import org.springframework.web.reactive.function.server.bodyAndAwait +import org.springframework.web.reactive.function.server.json + +@Component +class ProductsHandler( + @Autowired var webClient: WebClient, + @Autowired var productRepository: ProductRepositoryCoroutines) { + + @FlowPreview + suspend fun findAll(request: ServerRequest): ServerResponse = + ServerResponse.ok().json().bodyAndAwait(productRepository.getAllProducts()) + + suspend fun findOneInStock(request: ServerRequest): ServerResponse { + val id = request.pathVariable("id").toInt() + + val product: Deferred = GlobalScope.async { + productRepository.getProductById(id) + } + val quantity: Deferred = GlobalScope.async { + webClient.get() + .uri("/stock-service/product/$id/quantity") + .accept(MediaType.APPLICATION_JSON) + .awaitExchange().awaitBody() + } + return ServerResponse.ok().json().bodyAndAwait(ProductStockView(product.await()!!, quantity.await())) + } + + suspend fun findOne(request: ServerRequest): ServerResponse { + val id = request.pathVariable("id").toInt() + return ServerResponse.ok().json().bodyAndAwait(productRepository.getProductById(id)!!) + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/model/Product.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/model/Product.kt new file mode 100644 index 0000000000..c6dcbdc9c4 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/model/Product.kt @@ -0,0 +1,7 @@ +package com.baeldung.nonblockingcoroutines.model + +data class Product( + var id: Int = 0, + var name: String = "", + var price: Float = 0.0f +) diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepository.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepository.kt new file mode 100644 index 0000000000..20c3827c26 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepository.kt @@ -0,0 +1,34 @@ +package com.baeldung.nonblockingcoroutines.repository + +import com.baeldung.nonblockingcoroutines.model.Product +import org.springframework.data.r2dbc.function.DatabaseClient +import org.springframework.stereotype.Repository +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono + +@Repository +class ProductRepository(private val client: DatabaseClient) { + + fun getProductById(id: Int): Mono { + return client.execute().sql("SELECT * FROM products WHERE id = $1") + .bind(0, id) + .`as`(Product::class.java) + .fetch() + .one() + } + + fun addNewProduct(name: String, price: Float): Mono { + return client.execute() + .sql("INSERT INTO products (name, price) VALUES($1, $2)") + .bind(0, name) + .bind(1, price) + .then() + } + + fun getAllProducts(): Flux { + return client.select().from("products") + .`as`(Product::class.java) + .fetch() + .all() + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepositoryCoroutines.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepositoryCoroutines.kt new file mode 100644 index 0000000000..60a19d4d00 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/nonblockingcoroutines/repository/ProductRepositoryCoroutines.kt @@ -0,0 +1,40 @@ +package com.baeldung.nonblockingcoroutines.repository + + +import com.baeldung.nonblockingcoroutines.model.Product +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.reactive.awaitFirstOrNull +import kotlinx.coroutines.reactive.flow.asFlow +import org.springframework.data.r2dbc.function.DatabaseClient +import org.springframework.stereotype.Repository + +@Repository +class ProductRepositoryCoroutines(private val client: DatabaseClient) { + + suspend fun getProductById(id: Int): Product? = + client.execute().sql("SELECT * FROM products WHERE id = $1") + .bind(0, id) + .`as`(Product::class.java) + .fetch() + .one() + .awaitFirstOrNull() + + suspend fun addNewProduct(name: String, price: Float) = + client.execute() + .sql("INSERT INTO products (name, price) VALUES($1, $2)") + .bind(0, name) + .bind(1, price) + .then() + .awaitFirstOrNull() + + @FlowPreview + fun getAllProducts(): Flow = + client.select() + .from("products") + .`as`(Product::class.java) + .fetch() + .all() + .log() + .asFlow() +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/resources/application.properties b/spring-boot-kotlin/src/main/resources/application.properties new file mode 100644 index 0000000000..0f84ff2d75 --- /dev/null +++ b/spring-boot-kotlin/src/main/resources/application.properties @@ -0,0 +1,8 @@ +logging.level.org.springframework.data.r2dbc=DEBUG +logging.level.org.springframework.web.reactive.function.client.ExchangeFunctions=TRACE +spring.http.log-request-details=true +spring.h2.console.enabled=true +spring.datasource.username=sa +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.password= +spring.datasource.dbname=testdb \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/resources/logback.xml b/spring-boot-kotlin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-kotlin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-kotlin/src/test/kotlin/com/baeldung/nonblockingcoroutines/ProductHandlerTest.kt b/spring-boot-kotlin/src/test/kotlin/com/baeldung/nonblockingcoroutines/ProductHandlerTest.kt new file mode 100644 index 0000000000..53b1d50f21 --- /dev/null +++ b/spring-boot-kotlin/src/test/kotlin/com/baeldung/nonblockingcoroutines/ProductHandlerTest.kt @@ -0,0 +1,58 @@ +package com.baeldung.nonblockingcoroutines + +import com.baeldung.nonblockingcoroutines.config.RouterConfiguration +import com.baeldung.nonblockingcoroutines.handlers.ProductsHandler +import com.baeldung.nonblockingcoroutines.model.Product +import com.baeldung.nonblockingcoroutines.repository.ProductRepositoryCoroutines +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.reactive.flow.asFlow +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.BDDMockito.given +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration +import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit4.SpringRunner +import org.springframework.test.web.reactive.server.WebTestClient +import org.springframework.test.web.reactive.server.expectBodyList +import org.springframework.web.reactive.function.client.WebClient +import reactor.core.publisher.Flux +import org.springframework.test.context.ContextConfiguration + +@WebFluxTest( + excludeAutoConfiguration = [ReactiveUserDetailsServiceAutoConfiguration::class, ReactiveSecurityAutoConfiguration::class] +) +@RunWith(SpringRunner::class) +@ContextConfiguration(classes = [ProductsHandler::class, RouterConfiguration::class]) +class ProductHandlerTest { + + @Autowired + private lateinit var client: WebTestClient + + @MockBean + private lateinit var webClient: WebClient + + @MockBean + private lateinit var productsRepository: ProductRepositoryCoroutines + + + @FlowPreview + @Test + public fun `get all products`() { + val productsFlow = Flux.just( + Product(1, "product1", 1000.0F), + Product(2, "product2", 2000.0F), + Product(3, "product3", 3000.0F) + ).asFlow() + given(productsRepository.getAllProducts()).willReturn(productsFlow) + client.get() + .uri("/") + .exchange() + .expectStatus() + .isOk + .expectBodyList() + } + +} From 7672e03ec14e7af0ff6455ecac6b5b39024264e0 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 13 Jul 2019 18:29:33 +0530 Subject: [PATCH 52/74] [BAEL-10895] - Fixed tests in spring-5-data-reactive module --- spring-5-data-reactive/pom.xml | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml index 056fb37a52..5372803842 100644 --- a/spring-5-data-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -77,29 +77,34 @@ org.springframework spring-tx - 5.2.0.M2 + ${spring-tx.version} org.springframework.data spring-data-r2dbc - 1.0.0.M2 + ${spring-data-r2dbc.version} io.r2dbc r2dbc-h2 - 0.8.0.M8 + ${r2dbc-h2.version} com.h2database h2 - 1.4.199 + ${h2.version} org.springframework.boot spring-boot-starter-test test + + org.apache.httpcomponents + httpclient + ${httpclient.version} + @@ -195,11 +200,6 @@
- - 1.2.40 - 1.2.40 - - spring-snapshots @@ -216,5 +216,15 @@ + + 1.2.40 + 1.2.40 + 5.2.0.M2 + 1.0.0.M2 + 0.8.0.M8 + 4.5.2 + 1.4.199 + + From 54aeed4bc304b07d7b1ef39f648813345b62ca22 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 13 Jul 2019 16:36:16 +0300 Subject: [PATCH 53/74] add java sources to maveb --- spring-5-mvc/pom.xml | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/spring-5-mvc/pom.xml b/spring-5-mvc/pom.xml index 5fb8f66f71..302080a8b4 100644 --- a/spring-5-mvc/pom.xml +++ b/spring-5-mvc/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 com.baeldung @@ -51,12 +52,10 @@ org.jetbrains.kotlin kotlin-stdlib-jre8 - ${kotlin.version} org.jetbrains.kotlin kotlin-reflect - ${kotlin.version} com.fasterxml.jackson.module @@ -91,7 +90,6 @@ - ${project.basedir}/src/main/kotlin ${project.basedir}/src/test/kotlin @@ -132,11 +130,43 @@ + + org.codehaus.mojo + build-helper-maven-plugin + + + generate-sources + + add-source + + + + ${basedir}/src/main/java + ${basedir}/src/main/kotlin + + + + + test-compile + test-compile + + add-test-source + + + + ${basedir}/src/test/java + ${basedir}/src/test/kotlin + + + + + - + 2.9.0 1.1.2 + com.baeldung.Spring5Application From 550d1eac6dd018e7661f142406839a8b9a899de5 Mon Sep 17 00:00:00 2001 From: Anshul Bansal Date: Sat, 13 Jul 2019 22:08:49 +0300 Subject: [PATCH 54/74] BAEL-2995 - possible lossy conversion - conflicts resolved --- pom.xml | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index 2f83b92b2c..33411ca43a 100644 --- a/pom.xml +++ b/pom.xml @@ -988,29 +988,6 @@ jws libraries - jackson - jackson-2 - jackson-simple - java-collections-conversions - java-collections-maps - java-collections-maps-2 - - java-ee-8-security-api - java-lite - java-numbers - java-numbers-2 - java-rmi - java-spi - java-streams - java-streams-2 - java-strings - java-strings-2 - java-vavr-stream - java-websocket - javafx - javax-servlets - javaxval - jaxb persistence-modules/hibernate5 persistence-modules/hibernate-mapping persistence-modules/java-jpa @@ -1170,6 +1147,7 @@ java-ee-8-security-api java-lite java-numbers + java-numbers-2 java-rmi java-spi java-streams @@ -1182,6 +1160,8 @@ javax-servlets javaxval jaxb + jee-7-security jersey JGit From f4a0913e79d25f3c442a13358fea0993e9ee8235 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sun, 14 Jul 2019 18:40:26 +0530 Subject: [PATCH 55/74] [BAEL-15942] - POM Properties Cleanup --- apache-olingo/olingo2/pom.xml | 1 - aws/pom.xml | 1 - core-groovy-2/pom.xml | 2 - core-java-modules/core-java-8/pom.xml | 1 - .../core-java-concurrency-advanced/pom.xml | 1 - .../core-java-concurrency-basic/pom.xml | 2 - .../core-java-concurrency-collections/pom.xml | 1 - core-java-modules/core-java-io/pom.xml | 1 - core-java-modules/core-java-jvm/pom.xml | 1 - core-java-modules/core-java-lang-oop/pom.xml | 6 -- core-java-modules/core-java-lang/pom.xml | 3 - .../core-java-networking/pom.xml | 2 - core-java-modules/core-java-optional/pom.xml | 6 +- core-java-modules/core-java-os/pom.xml | 1 - core-java-modules/core-java-perf/pom.xml | 7 --- core-java-modules/core-java-security/pom.xml | 1 - core-java-modules/core-java-sun/pom.xml | 1 - core-java-modules/core-java/pom.xml | 5 +- core-kotlin-io/pom.xml | 4 +- core-kotlin/pom.xml | 4 +- couchbase/pom.xml | 1 - disruptor/pom.xml | 1 - dozer/pom.xml | 1 - flyway-cdi-extension/pom.xml | 1 - gson/pom.xml | 1 - guava-collections/pom.xml | 1 - guava/pom.xml | 1 - httpclient-simple/pom.xml | 2 - httpclient/pom.xml | 1 - hystrix/pom.xml | 1 - jackson-simple/pom.xml | 1 - jackson/pom.xml | 1 - java-collections-conversions/pom.xml | 1 - java-collections-maps-2/pom.xml | 1 - java-collections-maps/pom.xml | 1 - java-dates/pom.xml | 2 - java-ee-8-security-api/pom.xml | 2 - java-numbers/pom.xml | 1 - java-streams/pom.xml | 1 - javax-servlets/pom.xml | 1 - jaxb/pom.xml | 2 - jee-7/pom.xml | 2 - jee-kotlin/pom.xml | 61 +++++++++---------- jersey/pom.xml | 1 - jsf/pom.xml | 3 - jws/pom.xml | 1 - kotlin-libraries/pom.xml | 3 +- libraries-apache-commons/pom.xml | 7 +-- libraries-data/pom.xml | 1 - libraries-server/pom.xml | 3 +- libraries/pom.xml | 5 +- logging-modules/log-mdc/pom.xml | 1 - maven/pom.xml | 2 - parent-spring-4/pom.xml | 3 +- parent-spring-5/pom.xml | 3 +- patterns/design-patterns-2/pom.xml | 1 - patterns/pom.xml | 1 - persistence-modules/deltaspike/pom.xml | 1 - .../spring-hibernate-3/pom.xml | 1 - .../spring-hibernate-5/pom.xml | 1 - persistence-modules/spring-hibernate4/pom.xml | 1 - persistence-modules/spring-jpa/pom.xml | 4 -- .../spring-persistence-simple/pom.xml | 1 - pom.xml | 1 + resteasy/pom.xml | 1 - spring-5-webflux/pom.xml | 1 - spring-boot-angular/pom.xml | 4 -- spring-cloud/spring-cloud-contract/pom.xml | 1 - spring-core-2/pom.xml | 5 +- spring-core/pom.xml | 1 - spring-dispatcher-servlet/pom.xml | 1 - spring-exceptions/pom.xml | 2 - spring-jersey/pom.xml | 5 +- spring-jms/pom.xml | 1 - spring-jooq/pom.xml | 4 +- spring-katharsis/pom.xml | 1 - spring-mvc-forms-jsp/pom.xml | 1 - spring-mvc-simple/pom.xml | 6 +- spring-mvc-velocity/pom.xml | 1 - spring-mvc-webflow/pom.xml | 1 - spring-mvc-xml/pom.xml | 6 +- spring-rest-angular/pom.xml | 1 - spring-rest-full/pom.xml | 1 - spring-rest-query-language/pom.xml | 1 - spring-rest-simple/pom.xml | 1 - spring-rest/pom.xml | 1 - spring-resttemplate/pom.xml | 1 - spring-security-mvc-custom/pom.xml | 2 - spring-security-mvc-digest-auth/pom.xml | 2 - spring-security-mvc-jsonview/pom.xml | 8 +-- spring-security-mvc-login/pom.xml | 1 - .../pom.xml | 7 +-- spring-security-mvc-session/pom.xml | 1 - spring-security-mvc-socket/pom.xml | 3 +- spring-security-react/pom.xml | 2 - spring-security-rest-basic-auth/pom.xml | 1 - spring-security-rest-custom/pom.xml | 1 - spring-security-rest/pom.xml | 1 - spring-soap/pom.xml | 1 - spring-social-login/pom.xml | 4 -- spring-static-resources/pom.xml | 5 +- spring-userservice/pom.xml | 4 -- spring-zuul/pom.xml | 4 -- struts-2/pom.xml | 1 - tensorflow-java/pom.xml | 5 +- testing-modules/junit-5-basics/pom.xml | 1 - .../load-testing-comparison/pom.xml | 1 - testing-modules/mockito/pom.xml | 1 - testing-modules/rest-assured/pom.xml | 2 - testing-modules/rest-testing/pom.xml | 4 -- testing-modules/spring-testing/pom.xml | 4 +- testing-modules/test-containers/pom.xml | 1 - vaadin/pom.xml | 1 - video-tutorials/jackson-annotations/pom.xml | 4 -- xml/pom.xml | 6 -- 115 files changed, 60 insertions(+), 250 deletions(-) diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/olingo2/pom.xml index e3647b9c57..24e7b4e0b2 100644 --- a/apache-olingo/olingo2/pom.xml +++ b/apache-olingo/olingo2/pom.xml @@ -82,7 +82,6 @@ - 1.8 2.0.11 diff --git a/aws/pom.xml b/aws/pom.xml index 560f9145f9..75d5aac1eb 100644 --- a/aws/pom.xml +++ b/aws/pom.xml @@ -112,7 +112,6 @@ - 2.5 1.3.0 1.1.0 2.8.0 diff --git a/core-groovy-2/pom.xml b/core-groovy-2/pom.xml index 53b3e6a7ec..ba3fd0802b 100644 --- a/core-groovy-2/pom.xml +++ b/core-groovy-2/pom.xml @@ -175,8 +175,6 @@ 1.0.0 2.4.0 1.1-groovy-2.4 - 3.9 - 1.8 3.8.1 1.2.3 2.5.7 diff --git a/core-java-modules/core-java-8/pom.xml b/core-java-modules/core-java-8/pom.xml index c09c970e07..28182e515b 100644 --- a/core-java-modules/core-java-8/pom.xml +++ b/core-java-modules/core-java-8/pom.xml @@ -175,7 +175,6 @@ - 3.5 3.6.1 4.1 4.01 diff --git a/core-java-modules/core-java-concurrency-advanced/pom.xml b/core-java-modules/core-java-concurrency-advanced/pom.xml index a3ac7aa88a..5d41909ed3 100644 --- a/core-java-modules/core-java-concurrency-advanced/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced/pom.xml @@ -72,7 +72,6 @@ 21.0 - 3.5 3.6.1 4.1 4.01 diff --git a/core-java-modules/core-java-concurrency-basic/pom.xml b/core-java-modules/core-java-concurrency-basic/pom.xml index aea4bef6a7..96b3ef76f7 100644 --- a/core-java-modules/core-java-concurrency-basic/pom.xml +++ b/core-java-modules/core-java-concurrency-basic/pom.xml @@ -45,8 +45,6 @@ - - 3.5 3.6.1 1.7.0 diff --git a/core-java-modules/core-java-concurrency-collections/pom.xml b/core-java-modules/core-java-concurrency-collections/pom.xml index 27aae4ea6c..ea3bbe44f3 100644 --- a/core-java-modules/core-java-concurrency-collections/pom.xml +++ b/core-java-modules/core-java-concurrency-collections/pom.xml @@ -62,7 +62,6 @@ 21.0 - 3.5 3.6.1 4.1 4.01 diff --git a/core-java-modules/core-java-io/pom.xml b/core-java-modules/core-java-io/pom.xml index 44c703ee68..1a133d2cbe 100644 --- a/core-java-modules/core-java-io/pom.xml +++ b/core-java-modules/core-java-io/pom.xml @@ -248,7 +248,6 @@ - 3.5 1.55 1.10 3.6.1 diff --git a/core-java-modules/core-java-jvm/pom.xml b/core-java-modules/core-java-jvm/pom.xml index 6c700cd005..b1860322a6 100644 --- a/core-java-modules/core-java-jvm/pom.xml +++ b/core-java-modules/core-java-jvm/pom.xml @@ -35,7 +35,6 @@ - 3.5 3.6.1 diff --git a/core-java-modules/core-java-lang-oop/pom.xml b/core-java-modules/core-java-lang-oop/pom.xml index c9bb3b3e5a..46003b132b 100644 --- a/core-java-modules/core-java-lang-oop/pom.xml +++ b/core-java-modules/core-java-lang-oop/pom.xml @@ -75,13 +75,7 @@ - - - 2.8.5 2.8.2 - - - 3.5 3.10.0 3.0.3 diff --git a/core-java-modules/core-java-lang/pom.xml b/core-java-modules/core-java-lang/pom.xml index 45ccc8d0f5..8311636873 100644 --- a/core-java-modules/core-java-lang/pom.xml +++ b/core-java-modules/core-java-lang/pom.xml @@ -75,9 +75,6 @@ 2.8.2 - - - 3.5 1.5.0-b01 diff --git a/core-java-modules/core-java-networking/pom.xml b/core-java-modules/core-java-networking/pom.xml index 550ebdb4ff..e2ee7b2fcc 100644 --- a/core-java-modules/core-java-networking/pom.xml +++ b/core-java-modules/core-java-networking/pom.xml @@ -42,8 +42,6 @@ 1.5.0-b01 - 2.5 - 3.5 4.3.4.RELEASE diff --git a/core-java-modules/core-java-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml index f60e3ba03d..eb981c0907 100644 --- a/core-java-modules/core-java-optional/pom.xml +++ b/core-java-modules/core-java-optional/pom.xml @@ -19,12 +19,12 @@ com.h2database h2 - ${h2database.version} + ${h2.version} com.fasterxml.jackson.core jackson-databind - ${jackson.databind.version} + ${jackson.version} @@ -48,7 +48,5 @@ 1.8 1.8 5.4.0.Final - 1.4.197 - 2.9.8 \ No newline at end of file diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml index 85194b176e..f6c5ef04a5 100644 --- a/core-java-modules/core-java-os/pom.xml +++ b/core-java-modules/core-java-os/pom.xml @@ -68,7 +68,6 @@ - 3.5 4.1 4.01 diff --git a/core-java-modules/core-java-perf/pom.xml b/core-java-modules/core-java-perf/pom.xml index f225a9554b..b9c9d30ac0 100644 --- a/core-java-modules/core-java-perf/pom.xml +++ b/core-java-modules/core-java-perf/pom.xml @@ -23,11 +23,4 @@ - - - - 3.8.1 - - - diff --git a/core-java-modules/core-java-security/pom.xml b/core-java-modules/core-java-security/pom.xml index ed82a5209a..d3efb26fe8 100644 --- a/core-java-modules/core-java-security/pom.xml +++ b/core-java-modules/core-java-security/pom.xml @@ -43,7 +43,6 @@ - 3.8.1 1.60 1.11 diff --git a/core-java-modules/core-java-sun/pom.xml b/core-java-modules/core-java-sun/pom.xml index da27564d96..ab5f945114 100644 --- a/core-java-modules/core-java-sun/pom.xml +++ b/core-java-modules/core-java-sun/pom.xml @@ -264,7 +264,6 @@ 23.0 - 3.5 1.55 1.10 3.6.1 diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml index 2f33212c38..2a2cb3a6af 100644 --- a/core-java-modules/core-java/pom.xml +++ b/core-java-modules/core-java/pom.xml @@ -113,7 +113,7 @@ com.h2database h2 - ${h2database.version} + ${h2.version} @@ -453,8 +453,6 @@ 2.8.2 - 3.9 - 2.5 3.6.1 1.0.3 0.4 @@ -471,7 +469,6 @@ 2.21.0 1.1 - 1.4.197 2.1.0.1 1.19 diff --git a/core-kotlin-io/pom.xml b/core-kotlin-io/pom.xml index a0b688a223..78b36626d6 100644 --- a/core-kotlin-io/pom.xml +++ b/core-kotlin-io/pom.xml @@ -22,7 +22,7 @@ org.junit.jupiter junit-jupiter - ${junit.jupiter.version} + ${junit-jupiter.version} test @@ -88,7 +88,7 @@ 1.3.30 - 5.4.2 + 5.4.2 2.27.0 1.9.12 3.10.0 diff --git a/core-kotlin/pom.xml b/core-kotlin/pom.xml index 5de986b49e..e4d243360a 100644 --- a/core-kotlin/pom.xml +++ b/core-kotlin/pom.xml @@ -39,7 +39,7 @@ com.h2database h2 - ${h2database.version} + ${h2.version} com.github.kittinunf.fuel @@ -76,11 +76,9 @@ 3.6.1 - 3.8.1 1.1.1 5.2.0 3.10.0 - 1.4.197 1.15.0 3.3.0 1.16.1 diff --git a/couchbase/pom.xml b/couchbase/pom.xml index 31e6a53388..fc40749c61 100644 --- a/couchbase/pom.xml +++ b/couchbase/pom.xml @@ -69,7 +69,6 @@ 2.5.0 4.3.5.RELEASE - 3.5 diff --git a/disruptor/pom.xml b/disruptor/pom.xml index 296704f546..e1d78e7ed6 100644 --- a/disruptor/pom.xml +++ b/disruptor/pom.xml @@ -115,7 +115,6 @@ - 3.5 3.3.6 6.10 diff --git a/dozer/pom.xml b/dozer/pom.xml index 5720001acf..8234eb4c79 100644 --- a/dozer/pom.xml +++ b/dozer/pom.xml @@ -26,7 +26,6 @@ - 3.5 5.5.1 diff --git a/flyway-cdi-extension/pom.xml b/flyway-cdi-extension/pom.xml index f9f951880e..e8b327e35f 100644 --- a/flyway-cdi-extension/pom.xml +++ b/flyway-cdi-extension/pom.xml @@ -58,6 +58,5 @@ 5.1.4 8.5.33 1.3.2 - 1.4.197 diff --git a/gson/pom.xml b/gson/pom.xml index a21d783c39..9d2cf630d0 100644 --- a/gson/pom.xml +++ b/gson/pom.xml @@ -64,7 +64,6 @@ 2.8.0 - 3.5 4.1 2.9.6 diff --git a/guava-collections/pom.xml b/guava-collections/pom.xml index a717023156..ecda3c9595 100644 --- a/guava-collections/pom.xml +++ b/guava-collections/pom.xml @@ -55,7 +55,6 @@ 24.0-jre - 3.5 4.1 diff --git a/guava/pom.xml b/guava/pom.xml index 1d37a79ab6..34eb7eafa6 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -49,7 +49,6 @@ 24.0-jre - 3.5 3.6.1 diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index efcf0452e2..7dd54c8fc4 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -297,7 +297,6 @@ 19.0 - 3.5 1.10 4.1.4 @@ -305,7 +304,6 @@ 4.4.11 4.5.8 - 2.6 1.6.1 diff --git a/httpclient/pom.xml b/httpclient/pom.xml index def3a05816..8cd483cfc6 100644 --- a/httpclient/pom.xml +++ b/httpclient/pom.xml @@ -120,7 +120,6 @@ 19.0 - 3.5 1.10 4.1.4 diff --git a/hystrix/pom.xml b/hystrix/pom.xml index 7bb3e98246..e08af2c40f 100644 --- a/hystrix/pom.xml +++ b/hystrix/pom.xml @@ -65,7 +65,6 @@ 1.5.8 0.20.7 - 2.6 2.7 1.5.8 1.5.8 diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml index 5023ad87b6..05c1ef4595 100644 --- a/jackson-simple/pom.xml +++ b/jackson-simple/pom.xml @@ -118,7 +118,6 @@ - 3.8 2.10 2.8.5 4.2 diff --git a/jackson/pom.xml b/jackson/pom.xml index 948248d255..8a083525a2 100644 --- a/jackson/pom.xml +++ b/jackson/pom.xml @@ -118,7 +118,6 @@ - 3.8 2.10 2.8.5 4.2 diff --git a/java-collections-conversions/pom.xml b/java-collections-conversions/pom.xml index ee7221b25e..24d918d105 100644 --- a/java-collections-conversions/pom.xml +++ b/java-collections-conversions/pom.xml @@ -33,7 +33,6 @@ - 3.5 4.1 3.6.1 diff --git a/java-collections-maps-2/pom.xml b/java-collections-maps-2/pom.xml index 5f27eaa2d8..e242a8655e 100644 --- a/java-collections-maps-2/pom.xml +++ b/java-collections-maps-2/pom.xml @@ -54,7 +54,6 @@ 3.0.2 8.1.0 1.2.0 - 3.8.1 3.11.1 diff --git a/java-collections-maps/pom.xml b/java-collections-maps/pom.xml index b5eba31437..83cc97a21e 100644 --- a/java-collections-maps/pom.xml +++ b/java-collections-maps/pom.xml @@ -44,7 +44,6 @@ - 3.5 4.1 4.01 1.7.0 diff --git a/java-dates/pom.xml b/java-dates/pom.xml index d4f690d894..3fddf3f0f8 100644 --- a/java-dates/pom.xml +++ b/java-dates/pom.xml @@ -74,8 +74,6 @@ - - 3.5 2.10 3.6.1 diff --git a/java-ee-8-security-api/pom.xml b/java-ee-8-security-api/pom.xml index 9b8356714f..4d4e2ba3b3 100644 --- a/java-ee-8-security-api/pom.xml +++ b/java-ee-8-security-api/pom.xml @@ -72,8 +72,6 @@ 8.0 2.3 18.0.0.1 - - 3.2.2 diff --git a/java-numbers/pom.xml b/java-numbers/pom.xml index daed356f66..ac3ca2680f 100644 --- a/java-numbers/pom.xml +++ b/java-numbers/pom.xml @@ -121,7 +121,6 @@ 3.6.1 1.0.3 - 3.5 3.6.1 diff --git a/java-streams/pom.xml b/java-streams/pom.xml index b0c56ecdf9..bd0123e01d 100644 --- a/java-streams/pom.xml +++ b/java-streams/pom.xml @@ -106,7 +106,6 @@ - 3.5 0.9.0 1.15 0.6.5 diff --git a/javax-servlets/pom.xml b/javax-servlets/pom.xml index e3d8a430d9..096b1bb229 100644 --- a/javax-servlets/pom.xml +++ b/javax-servlets/pom.xml @@ -88,7 +88,6 @@ 3.9.1 2.21.0 1.3.3 - 2.6 4.0.1 diff --git a/jaxb/pom.xml b/jaxb/pom.xml index 3ed6d9b21a..d575f12c7b 100644 --- a/jaxb/pom.xml +++ b/jaxb/pom.xml @@ -130,8 +130,6 @@ 2.3 3.0.2 - 2.5 - 3.5 1.0.0 1.1 diff --git a/jee-7/pom.xml b/jee-7/pom.xml index d389b57cd5..9432801fd9 100644 --- a/jee-7/pom.xml +++ b/jee-7/pom.xml @@ -519,11 +519,9 @@ 1.13 2.25 1.0.0.Final - 2.6 4.2.3.RELEASE 2.21.0 1.1.2 - 2.4 2.2.14 4.5 2.0.1.Final diff --git a/jee-kotlin/pom.xml b/jee-kotlin/pom.xml index 963c03d0df..17163ba23c 100644 --- a/jee-kotlin/pom.xml +++ b/jee-kotlin/pom.xml @@ -2,43 +2,16 @@ 4.0.0 + jee-kotlin + jee-kotlin + war + parent-modules com.baeldung 1.0.0-SNAPSHOT - jee-kotlin - jee-kotlin - war - - - UTF-8 - false - 8.0 - - - 1.3.41 - official - true - - - 8.2.1.Final - 3.2.3 - 2.21.0 - 3.1.1 - - 1.4.1.Final - 2.0.1.Final - 1.0.0.Alpha4 - - 4.12 - 3.8.0.Final - 2.9.8 - 3.1.3 - - - org.jetbrains.kotlin @@ -134,7 +107,7 @@ org.apache.maven.plugins maven-war-plugin - ${mvn-war-plugin.version} + ${maven-war-plugin.version} webapp kotlin @@ -286,4 +259,28 @@ + + + UTF-8 + false + 8.0 + + + 1.3.41 + official + true + + + 8.2.1.Final + 2.21.0 + 3.1.1 + + 1.4.1.Final + 2.0.1.Final + 1.0.0.Alpha4 + + 3.8.0.Final + 3.1.3 + + diff --git a/jersey/pom.xml b/jersey/pom.xml index a3adb4cf5a..708b36ce41 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -80,7 +80,6 @@ 2.26 - 3.2.0 diff --git a/jsf/pom.xml b/jsf/pom.xml index 19f1265250..31362a8809 100644 --- a/jsf/pom.xml +++ b/jsf/pom.xml @@ -99,9 +99,6 @@ 2.2.14 3.0.0 - - 2.6 - 6.2 diff --git a/jws/pom.xml b/jws/pom.xml index 6bc790e7ee..5c19c887d3 100644 --- a/jws/pom.xml +++ b/jws/pom.xml @@ -83,7 +83,6 @@ 3.0.2 - 3.0.0 1.6.0 1.6.0 diff --git a/kotlin-libraries/pom.xml b/kotlin-libraries/pom.xml index b75c77f358..e252329426 100644 --- a/kotlin-libraries/pom.xml +++ b/kotlin-libraries/pom.xml @@ -94,7 +94,7 @@ com.h2database h2 - ${h2database.version} + ${h2.version} @@ -184,7 +184,6 @@ 1.1.1 5.2.0 3.10.0 - 1.4.197 0.10.4 1.9.3 diff --git a/libraries-apache-commons/pom.xml b/libraries-apache-commons/pom.xml index cb5990df22..05d11d83fe 100644 --- a/libraries-apache-commons/pom.xml +++ b/libraries-apache-commons/pom.xml @@ -25,7 +25,7 @@ org.apache.commons commons-lang3 - ${commons-lang.version} + ${commons-lang3.version} org.apache.commons @@ -35,7 +35,7 @@ commons-io commons-io - ${commons.io.version} + ${commons-io.version} commons-chain @@ -87,13 +87,12 @@ - 3.6 + 3.6 1.1 1.9.3 1.2 1.4 3.6.2 - 2.5 1.6 4.1 2.0.0.0 diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 31aaaea951..88dcceafaa 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -449,7 +449,6 @@ 2.8.2 1.1.0 1.5.0 - 2.9.7 3.0.0 3.6.2 3.8.4 diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml index 72794729a5..9bed5e211b 100644 --- a/libraries-server/pom.xml +++ b/libraries-server/pom.xml @@ -52,7 +52,7 @@ commons-io commons-io - ${commons.io.version} + ${commons-io.version} io.netty @@ -114,7 +114,6 @@ 3.6.2 4.5.3 - 2.5 9.4.8.v20171121 4.1.20.Final 4.1 diff --git a/libraries/pom.xml b/libraries/pom.xml index 8e787bdc22..e8ffde5f99 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -45,7 +45,7 @@ org.apache.commons commons-lang3 - ${commons-lang.version} + ${commons-lang3.version} commons-net @@ -818,7 +818,6 @@ 0.1.0 0.7.0 3.2.7 - 3.6 1.9.2 1.2 3.21.0-GA @@ -826,12 +825,10 @@ 1.5.0 3.1.0 4.5.3 - 1.4.196 1.0 4.5.3 - 2.9.7 2.92 1.9.26 1.41.0 diff --git a/logging-modules/log-mdc/pom.xml b/logging-modules/log-mdc/pom.xml index ae658e034e..ce58f43e4e 100644 --- a/logging-modules/log-mdc/pom.xml +++ b/logging-modules/log-mdc/pom.xml @@ -101,7 +101,6 @@ 2.7 3.3.6 3.3.0.Final - 2.4 diff --git a/maven/pom.xml b/maven/pom.xml index 96643d76f3..ef6e7b7d93 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -299,7 +299,6 @@ - 1.8 3.0.2 3.8.0 2.22.0 @@ -310,6 +309,5 @@ Baeldung 9.4.11.v20180605 2.27 - 4.12 \ No newline at end of file diff --git a/parent-spring-4/pom.xml b/parent-spring-4/pom.xml index d7eea44989..b08ead02d4 100644 --- a/parent-spring-4/pom.xml +++ b/parent-spring-4/pom.xml @@ -23,14 +23,13 @@ org.junit.jupiter junit-jupiter-engine - ${junit.jupiter.version} + ${junit-jupiter.version} test 4.3.22.RELEASE - 5.0.2 \ No newline at end of file diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index 84df8cf30a..f85924b801 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -23,14 +23,13 @@ org.junit.jupiter junit-jupiter-engine - ${junit.jupiter.version} + ${junit-jupiter.version} test 5.1.4.RELEASE - 5.0.2 5.1.4.RELEASE diff --git a/patterns/design-patterns-2/pom.xml b/patterns/design-patterns-2/pom.xml index 5c3e70b046..392035ab84 100644 --- a/patterns/design-patterns-2/pom.xml +++ b/patterns/design-patterns-2/pom.xml @@ -38,6 +38,5 @@ 1.8 1.8 16.0.2 - 3.5 diff --git a/patterns/pom.xml b/patterns/pom.xml index 875af67d55..2be9d2519e 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -51,7 +51,6 @@ - 3.0.0 9.4.0.v20161208 diff --git a/persistence-modules/deltaspike/pom.xml b/persistence-modules/deltaspike/pom.xml index 4dcef07695..46e774edff 100644 --- a/persistence-modules/deltaspike/pom.xml +++ b/persistence-modules/deltaspike/pom.xml @@ -317,7 +317,6 @@ 2.6 1.1.3 1.2.5.Final-redhat-1 - 3.5 diff --git a/persistence-modules/spring-hibernate-3/pom.xml b/persistence-modules/spring-hibernate-3/pom.xml index ec35f35bb3..4349492370 100644 --- a/persistence-modules/spring-hibernate-3/pom.xml +++ b/persistence-modules/spring-hibernate-3/pom.xml @@ -93,7 +93,6 @@ 8.5.8 19.0 - 3.5 diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index 16e55cb0c0..e27775c76f 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -146,7 +146,6 @@ 21.0 - 3.5 diff --git a/persistence-modules/spring-hibernate4/pom.xml b/persistence-modules/spring-hibernate4/pom.xml index 4289c9c3d5..388e2ab27b 100644 --- a/persistence-modules/spring-hibernate4/pom.xml +++ b/persistence-modules/spring-hibernate4/pom.xml @@ -167,7 +167,6 @@ 19.0 - 3.5 4.4.1 4.5 diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml index 0fdffad8db..0961cabaff 100644 --- a/persistence-modules/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -174,11 +174,7 @@ 21.0 - 3.5 3.8.0 - - - 2.6 \ No newline at end of file diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml index 1afacab164..d0b3f5fe29 100644 --- a/persistence-modules/spring-persistence-simple/pom.xml +++ b/persistence-modules/spring-persistence-simple/pom.xml @@ -147,7 +147,6 @@ 21.0 - 3.5 3.8.0 diff --git a/pom.xml b/pom.xml index f40659bc16..bfd8adeb7a 100644 --- a/pom.xml +++ b/pom.xml @@ -1557,6 +1557,7 @@ 2.21.0 2.5 2.6 + 3.5 1.4 3.0.0 3.1.0 diff --git a/resteasy/pom.xml b/resteasy/pom.xml index ca4124abca..8aea8077f9 100644 --- a/resteasy/pom.xml +++ b/resteasy/pom.xml @@ -143,7 +143,6 @@ 3.0.19.Final - 2.5 1.6.1 diff --git a/spring-5-webflux/pom.xml b/spring-5-webflux/pom.xml index 6317723467..6887f01753 100644 --- a/spring-5-webflux/pom.xml +++ b/spring-5-webflux/pom.xml @@ -99,7 +99,6 @@ - 1.8 2.2.0.M3 diff --git a/spring-boot-angular/pom.xml b/spring-boot-angular/pom.xml index 62a2701dd0..71c46cb7f5 100644 --- a/spring-boot-angular/pom.xml +++ b/spring-boot-angular/pom.xml @@ -44,8 +44,4 @@ - - - 1.8 - diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml index ea71891648..a7ee52e954 100644 --- a/spring-cloud/spring-cloud-contract/pom.xml +++ b/spring-cloud/spring-cloud-contract/pom.xml @@ -56,7 +56,6 @@ UTF-8 UTF-8 - 1.8 2.1.1.RELEASE 2.1.4.RELEASE diff --git a/spring-core-2/pom.xml b/spring-core-2/pom.xml index bb4ca9701b..20cd900e00 100644 --- a/spring-core-2/pom.xml +++ b/spring-core-2/pom.xml @@ -31,13 +31,13 @@ org.junit.jupiter junit-jupiter-engine - ${junit.jupiter.version} + ${junit-jupiter.version} test org.junit.jupiter junit-jupiter-api - ${junit.jupiter.version} + ${junit-jupiter.version} test @@ -54,7 +54,6 @@ 5.1.4.RELEASE - 5.0.2 \ No newline at end of file diff --git a/spring-core/pom.xml b/spring-core/pom.xml index 75e9fd7131..7e5a9b3feb 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -87,7 +87,6 @@ 1.4.4.RELEASE 1 20.0 - 2.6 2.5 1.5.2.RELEASE 1.10.19 diff --git a/spring-dispatcher-servlet/pom.xml b/spring-dispatcher-servlet/pom.xml index eb0fdfea46..6f816986be 100644 --- a/spring-dispatcher-servlet/pom.xml +++ b/spring-dispatcher-servlet/pom.xml @@ -96,7 +96,6 @@ 3.0-r1655215 - 3.0.0 \ No newline at end of file diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml index ff28ac89bb..45c80f2c9f 100644 --- a/spring-exceptions/pom.xml +++ b/spring-exceptions/pom.xml @@ -192,7 +192,6 @@ 19.0 - 3.5 4.4.5 4.5.2 @@ -200,7 +199,6 @@ 2.9.0 - 2.6 2.7 1.6.1 diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 5a12d27180..e053ee7b4b 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -38,7 +38,7 @@ javax.servlet javax.servlet-api - ${servlet-api-version} + ${javax.servlet-api.version} provided @@ -223,11 +223,10 @@ 2.27 - 3.2.0 1.6.1 4.4.9 4.5.5 - 4.0.0 + 4.0.0 1.58 3.10.0 1.5.10.RELEASE diff --git a/spring-jms/pom.xml b/spring-jms/pom.xml index 2ed58c0c95..ea4af32216 100644 --- a/spring-jms/pom.xml +++ b/spring-jms/pom.xml @@ -64,7 +64,6 @@ 4.3.4.RELEASE 5.14.1 - 2.6 diff --git a/spring-jooq/pom.xml b/spring-jooq/pom.xml index 8bce500a86..8a1fa877da 100644 --- a/spring-jooq/pom.xml +++ b/spring-jooq/pom.xml @@ -102,7 +102,7 @@ com.h2database h2 - ${com.h2database.version} + ${h2.version} @@ -189,8 +189,6 @@ 3.11.7 - 1.4.193 - 1.0.0 1.5 1.0.0 diff --git a/spring-katharsis/pom.xml b/spring-katharsis/pom.xml index 74786e7926..18bf198948 100644 --- a/spring-katharsis/pom.xml +++ b/spring-katharsis/pom.xml @@ -137,7 +137,6 @@ 3.0.2 0.9.10 1.6.1 - 3.7 diff --git a/spring-mvc-forms-jsp/pom.xml b/spring-mvc-forms-jsp/pom.xml index 20912e71e5..5ce2d19414 100644 --- a/spring-mvc-forms-jsp/pom.xml +++ b/spring-mvc-forms-jsp/pom.xml @@ -99,7 +99,6 @@ - 2.6 6.0.10.Final 1.3.3 5.2.5.Final diff --git a/spring-mvc-simple/pom.xml b/spring-mvc-simple/pom.xml index a767cf3c37..580a40e50b 100644 --- a/spring-mvc-simple/pom.xml +++ b/spring-mvc-simple/pom.xml @@ -47,7 +47,7 @@ commons-fileupload commons-fileupload - ${fileupload.version} + ${commons-fileupload.version} org.springframework @@ -162,18 +162,16 @@ 1.8 1.8 - 3.2.0 2.21.0 2.3.2-b02 4.0.0 6.0.10.Final enter-location-of-server - 1.3.2 + 1.3.2 3.0.7.RELEASE 2.4.12 2.3.27-incubating 1.2.5 - 1.0.2 1.9.0 1.4.9 5.1.0 diff --git a/spring-mvc-velocity/pom.xml b/spring-mvc-velocity/pom.xml index df19b67e8e..5954e48e8f 100644 --- a/spring-mvc-velocity/pom.xml +++ b/spring-mvc-velocity/pom.xml @@ -115,7 +115,6 @@ 2.9.0 - 2.6 2.7 1.6.1 diff --git a/spring-mvc-webflow/pom.xml b/spring-mvc-webflow/pom.xml index c8de990da0..219a2be689 100644 --- a/spring-mvc-webflow/pom.xml +++ b/spring-mvc-webflow/pom.xml @@ -94,7 +94,6 @@ 4.5.2 - 2.6 2.7 1.6.1 diff --git a/spring-mvc-xml/pom.xml b/spring-mvc-xml/pom.xml index c978bdd983..9f7a24b358 100644 --- a/spring-mvc-xml/pom.xml +++ b/spring-mvc-xml/pom.xml @@ -33,7 +33,7 @@ javax.servlet javax.servlet-api - ${javax.servlet.version} + ${javax.servlet-api.version} provided @@ -129,17 +129,13 @@ 6.0.10.Final - 1.2 - 3.1.0 3.0.1-b08 19.0 - 3.5 2.8.0 - 2.6 1.6.1 diff --git a/spring-rest-angular/pom.xml b/spring-rest-angular/pom.xml index 5240ae24e7..69becfb4ae 100644 --- a/spring-rest-angular/pom.xml +++ b/spring-rest-angular/pom.xml @@ -74,7 +74,6 @@ 19.0 - 3.5 org.baeldung.web.main.Application diff --git a/spring-rest-full/pom.xml b/spring-rest-full/pom.xml index a85393b7a8..5bc3a70ed5 100644 --- a/spring-rest-full/pom.xml +++ b/spring-rest-full/pom.xml @@ -287,7 +287,6 @@ 19.0 - 3.5 3.25.0-GA diff --git a/spring-rest-query-language/pom.xml b/spring-rest-query-language/pom.xml index 70fea91f31..7ee658d8ba 100644 --- a/spring-rest-query-language/pom.xml +++ b/spring-rest-query-language/pom.xml @@ -353,7 +353,6 @@ 19.0 - 3.5 1.7.0 diff --git a/spring-rest-simple/pom.xml b/spring-rest-simple/pom.xml index d301957eb9..263e451c62 100644 --- a/spring-rest-simple/pom.xml +++ b/spring-rest-simple/pom.xml @@ -323,7 +323,6 @@ 4.0.0 1.4 3.1.0 - 3.5 1.4.9 diff --git a/spring-rest/pom.xml b/spring-rest/pom.xml index 99bdd7646d..670bac9805 100644 --- a/spring-rest/pom.xml +++ b/spring-rest/pom.xml @@ -263,7 +263,6 @@ 4.0.0 1.4 3.1.0 - 3.5 20.0 diff --git a/spring-resttemplate/pom.xml b/spring-resttemplate/pom.xml index 06d4eed9fc..ae5cfed4c9 100644 --- a/spring-resttemplate/pom.xml +++ b/spring-resttemplate/pom.xml @@ -284,7 +284,6 @@ - 3.5 1.4.9 diff --git a/spring-security-mvc-custom/pom.xml b/spring-security-mvc-custom/pom.xml index 4e932f3245..3bae514bc1 100644 --- a/spring-security-mvc-custom/pom.xml +++ b/spring-security-mvc-custom/pom.xml @@ -194,10 +194,8 @@ 19.0 - 3.5 - 2.6 1.6.1 diff --git a/spring-security-mvc-digest-auth/pom.xml b/spring-security-mvc-digest-auth/pom.xml index cf1de1730d..0baaea15ef 100644 --- a/spring-security-mvc-digest-auth/pom.xml +++ b/spring-security-mvc-digest-auth/pom.xml @@ -196,13 +196,11 @@ 19.0 - 3.5 4.4.5 4.5.2 - 2.6 1.6.1 diff --git a/spring-security-mvc-jsonview/pom.xml b/spring-security-mvc-jsonview/pom.xml index 8fa7b4ffb5..a7f668ae8b 100644 --- a/spring-security-mvc-jsonview/pom.xml +++ b/spring-security-mvc-jsonview/pom.xml @@ -111,7 +111,7 @@ javax.servlet javax.servlet-api - ${javax.servlet.version} + ${javax.servlet-api.version} provided @@ -206,12 +206,6 @@ - - 3.1.0 - 1.2 - - - 2.6 1.6.1 2.4.0 diff --git a/spring-security-mvc-login/pom.xml b/spring-security-mvc-login/pom.xml index 02ed0e36f2..1ca11bc1ab 100644 --- a/spring-security-mvc-login/pom.xml +++ b/spring-security-mvc-login/pom.xml @@ -175,7 +175,6 @@ - 2.6 1.6.1 diff --git a/spring-security-mvc-persisted-remember-me/pom.xml b/spring-security-mvc-persisted-remember-me/pom.xml index 5e987dcb77..2f7989d573 100644 --- a/spring-security-mvc-persisted-remember-me/pom.xml +++ b/spring-security-mvc-persisted-remember-me/pom.xml @@ -99,7 +99,7 @@ javax.servlet javax.servlet-api - ${javax.servlet.version} + ${javax.servlet-api.version} provided @@ -200,15 +200,10 @@ 9.4.1212 - - 3.1.0 - 1.2 - 19.0 - 2.6 1.6.1 1.5.10.RELEASE diff --git a/spring-security-mvc-session/pom.xml b/spring-security-mvc-session/pom.xml index 276f651436..b55ce70517 100644 --- a/spring-security-mvc-session/pom.xml +++ b/spring-security-mvc-session/pom.xml @@ -119,7 +119,6 @@ 3.0.2 - 2.6 1.6.1 diff --git a/spring-security-mvc-socket/pom.xml b/spring-security-mvc-socket/pom.xml index f1d28355fd..f799a7fa9f 100644 --- a/spring-security-mvc-socket/pom.xml +++ b/spring-security-mvc-socket/pom.xml @@ -78,7 +78,7 @@ com.h2database h2 - ${h2database.version} + ${h2.version} @@ -186,7 +186,6 @@ 5.2.10.Final 4.2.3.RELEASE 1.11.3.RELEASE - 1.4.196 1.2.3 diff --git a/spring-security-react/pom.xml b/spring-security-react/pom.xml index c7b7c85be8..40c284af7f 100644 --- a/spring-security-react/pom.xml +++ b/spring-security-react/pom.xml @@ -169,10 +169,8 @@ 19.0 - 3.5 - 2.6 2.7 1.6 9.4.11.v20180605 diff --git a/spring-security-rest-basic-auth/pom.xml b/spring-security-rest-basic-auth/pom.xml index 8a90247386..78bab83db5 100644 --- a/spring-security-rest-basic-auth/pom.xml +++ b/spring-security-rest-basic-auth/pom.xml @@ -279,7 +279,6 @@ 19.0 - 2.6 1.6.1 diff --git a/spring-security-rest-custom/pom.xml b/spring-security-rest-custom/pom.xml index 2180b917e5..4bab9b9d95 100644 --- a/spring-security-rest-custom/pom.xml +++ b/spring-security-rest-custom/pom.xml @@ -206,7 +206,6 @@ 19.0 - 3.5 1.2 diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml index af38c1ffef..a66909a68e 100644 --- a/spring-security-rest/pom.xml +++ b/spring-security-rest/pom.xml @@ -271,7 +271,6 @@ 26.0-jre - 3.5 1.3.2 diff --git a/spring-soap/pom.xml b/spring-soap/pom.xml index 16f19b681f..e155a0f6b2 100644 --- a/spring-soap/pom.xml +++ b/spring-soap/pom.xml @@ -62,7 +62,6 @@ - 1.8 2.1.2.RELEASE diff --git a/spring-social-login/pom.xml b/spring-social-login/pom.xml index e948c908d4..655e885568 100644 --- a/spring-social-login/pom.xml +++ b/spring-social-login/pom.xml @@ -94,8 +94,4 @@ - - 3.3.2 - - \ No newline at end of file diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index 84519a37c1..b8068814ba 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -145,7 +145,7 @@ commons-io commons-io - ${commons.io.version} + ${commons-io.version} @@ -215,9 +215,6 @@ 1.5.1 - - - 2.5 \ No newline at end of file diff --git a/spring-userservice/pom.xml b/spring-userservice/pom.xml index e6e8553c80..cd61dfbf27 100644 --- a/spring-userservice/pom.xml +++ b/spring-userservice/pom.xml @@ -234,11 +234,7 @@ 19.0 - 3.5 1.4.01 - - - 2.6 \ No newline at end of file diff --git a/spring-zuul/pom.xml b/spring-zuul/pom.xml index fbbbdddbf7..a613f51c3f 100644 --- a/spring-zuul/pom.xml +++ b/spring-zuul/pom.xml @@ -39,10 +39,6 @@ 2.1.0.RELEASE - - 3.5 - - 2.6 \ No newline at end of file diff --git a/struts-2/pom.xml b/struts-2/pom.xml index 7de688ff2c..1f7d6876d5 100644 --- a/struts-2/pom.xml +++ b/struts-2/pom.xml @@ -70,7 +70,6 @@ 2.5.5 2.5.8 4.3.6.RELEASE - 3.0.0 \ No newline at end of file diff --git a/tensorflow-java/pom.xml b/tensorflow-java/pom.xml index f9abde737c..84d2f6cf21 100644 --- a/tensorflow-java/pom.xml +++ b/tensorflow-java/pom.xml @@ -24,13 +24,13 @@ org.junit.jupiter junit-jupiter-api - ${junit.jupiter.version} + ${junit-jupiter.version} test org.junit.jupiter junit-jupiter-engine - ${junit.jupiter.version} + ${junit-jupiter.version} test @@ -46,6 +46,5 @@ 1.12.0 - 5.4.0 \ No newline at end of file diff --git a/testing-modules/junit-5-basics/pom.xml b/testing-modules/junit-5-basics/pom.xml index f72c14ee65..68a0ceeee7 100644 --- a/testing-modules/junit-5-basics/pom.xml +++ b/testing-modules/junit-5-basics/pom.xml @@ -153,7 +153,6 @@ 5.4.2 1.2.0 5.4.2 - 1.4.196 5.0.6.RELEASE 2.21.0 diff --git a/testing-modules/load-testing-comparison/pom.xml b/testing-modules/load-testing-comparison/pom.xml index 44014e96ab..2c53657481 100644 --- a/testing-modules/load-testing-comparison/pom.xml +++ b/testing-modules/load-testing-comparison/pom.xml @@ -145,7 +145,6 @@ 5.0 3.11 2.0.5.RELEASE - 1.4.197 \ No newline at end of file diff --git a/testing-modules/mockito/pom.xml b/testing-modules/mockito/pom.xml index 19dbaa0dc1..7b6d6e7735 100644 --- a/testing-modules/mockito/pom.xml +++ b/testing-modules/mockito/pom.xml @@ -94,7 +94,6 @@ 2.0.9.RELEASE 19.0 - 3.5 1.7.0 diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index 4ed10f0641..eb85c6c8be 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -194,14 +194,12 @@ 18.0 - 2.9.7 1.8 19.0 2.5 1.4.7 9.4.0.v20161208 - 3.5 3.2.2 4.4.5 diff --git a/testing-modules/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml index 6dad3be117..a1995ce9ff 100644 --- a/testing-modules/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -151,7 +151,6 @@ 19.0 - 3.5 2.9.0 @@ -163,9 +162,6 @@ 4.5.2 4.1 - - - 2.6 \ No newline at end of file diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml index f4d7b5dc66..6f2700e2df 100644 --- a/testing-modules/spring-testing/pom.xml +++ b/testing-modules/spring-testing/pom.xml @@ -73,7 +73,7 @@ javax.servlet javax.servlet-api - ${servlet.api.version} + ${javax.servlet-api.version} @@ -94,7 +94,7 @@ 3.1.6 5.4.0 5.1.4.RELEASE - 4.0.1 + 4.0.1 2.1.1 diff --git a/testing-modules/test-containers/pom.xml b/testing-modules/test-containers/pom.xml index 7ee002ea8b..292af2051a 100644 --- a/testing-modules/test-containers/pom.xml +++ b/testing-modules/test-containers/pom.xml @@ -99,7 +99,6 @@ - 5.1.0 1.0.1 4.12.1 2.8.2 diff --git a/vaadin/pom.xml b/vaadin/pom.xml index 089ebe67c1..e3d882bbda 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -187,7 +187,6 @@ 1.8 local mytheme - 3.0.0 3.0.0 diff --git a/video-tutorials/jackson-annotations/pom.xml b/video-tutorials/jackson-annotations/pom.xml index 2492951d1a..200ca7577f 100644 --- a/video-tutorials/jackson-annotations/pom.xml +++ b/video-tutorials/jackson-annotations/pom.xml @@ -141,10 +141,6 @@ 2.8.0 4.1 - - 3.5 - 2.5 - 3.0.1 3.0.0 diff --git a/xml/pom.xml b/xml/pom.xml index e9b89c71fc..123875b1d9 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -249,18 +249,12 @@ 1.6.1 1.1.6 2.0.6 - 2.5 4.1 1.2.4.5 2.1 1.4.2 1.0-2 - - 3.5 - 2.4 - 1.8 - 1.3.1 From aac72242b6e6d93c21b08fc1555baa8fd32371a4 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Mon, 15 Jul 2019 09:56:25 +0300 Subject: [PATCH 56/74] Update README.md --- spring-mvc-kotlin/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-mvc-kotlin/README.md b/spring-mvc-kotlin/README.md index e5167f69fc..cc6827eb1b 100644 --- a/spring-mvc-kotlin/README.md +++ b/spring-mvc-kotlin/README.md @@ -2,3 +2,4 @@ - [Spring MVC Setup with Kotlin](http://www.baeldung.com/spring-mvc-kotlin) - [Working with Kotlin and JPA](http://www.baeldung.com/kotlin-jpa) - [Kotlin-allopen and Spring](http://www.baeldung.com/kotlin-allopen-spring) +- [MockMvc Kotlin DSL](https://www.baeldung.com/mockmvc-kotlin-dsl) From 81ae72d8a2ccf9ef6eca1f7026cf22ca3b939d83 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:09:03 -0700 Subject: [PATCH 57/74] Create README.md [skip.ci] --- core-java-modules/core-java-lambdas/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java-lambdas/README.md diff --git a/core-java-modules/core-java-lambdas/README.md b/core-java-modules/core-java-lambdas/README.md new file mode 100644 index 0000000000..10b876735e --- /dev/null +++ b/core-java-modules/core-java-lambdas/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables) From 0bcdf47ee791f77da3e014a06a3e9cda32520365 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:10:03 -0700 Subject: [PATCH 58/74] Update README.md [skip ci] --- quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quarkus/README.md b/quarkus/README.md index 01009eab3e..8116d16cb7 100644 --- a/quarkus/README.md +++ b/quarkus/README.md @@ -1,3 +1,3 @@ ## Relevant articles: -- [Guide to QuarkusIO](hhttps://www.baeldung.com/quarkus-io) +- [Guide to QuarkusIO](https://www.baeldung.com/quarkus-io) From aeb237ceb9fe5492b0f0a20a778841b7a3a50f1c Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:12:06 -0700 Subject: [PATCH 59/74] Create README.md [skip ci] --- core-java-modules/core-java-12/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java-12/README.md diff --git a/core-java-modules/core-java-12/README.md b/core-java-modules/core-java-12/README.md new file mode 100644 index 0000000000..4514fd1a2b --- /dev/null +++ b/core-java-modules/core-java-12/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api) From 4e93986e9bea4cb3c662390c938bac0f123b2032 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:13:32 -0700 Subject: [PATCH 60/74] Update README.MD [skip ci] --- java-strings-2/README.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/java-strings-2/README.MD b/java-strings-2/README.MD index 6548c48f2c..c6d4f0222a 100644 --- a/java-strings-2/README.MD +++ b/java-strings-2/README.MD @@ -4,3 +4,4 @@ - [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring) - [Removing Stopwords from a String in Java](https://www.baeldung.com/java-string-remove-stopwords) - [Blank and Empty Strings in Java](https://www.baeldung.com/java-blank-empty-strings) +- [String Initialization in Java](https://www.baeldung.com/java-string-initialization) From caec5d3d6ba530e2f2702655988c4e470fe01165 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:16:06 -0700 Subject: [PATCH 61/74] Create README.md [skip ci] --- .../src/main/java/com/baeldung/predicate/not/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/README.md diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/README.md b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/README.md new file mode 100644 index 0000000000..6f8f95970e --- /dev/null +++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Negate a Predicate Method Reference with Java 11](https://www.baeldung.com/java-negate-predicate-method-reference) From 16105dc94c5347ead953e9c454811946d2e419e6 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:17:07 -0700 Subject: [PATCH 62/74] Update README.md [skip ci] --- core-java-modules/core-java-concurrency-basic/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-basic/README.md b/core-java-modules/core-java-concurrency-basic/README.md index 6fa702fbe7..c498bed315 100644 --- a/core-java-modules/core-java-concurrency-basic/README.md +++ b/core-java-modules/core-java-concurrency-basic/README.md @@ -17,3 +17,4 @@ - [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable) - [What is Thread-Safety and How to Achieve it?](https://www.baeldung.com/java-thread-safety) - [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread) +- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution) From b360c8aa5801c837e6babfd5c1ee70a5b077d994 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:18:02 -0700 Subject: [PATCH 63/74] Update README.md [skip ci] --- persistence-modules/java-jpa/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 7edcd168e9..5a99217f45 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -13,3 +13,4 @@ - [Defining JPA Entities](https://www.baeldung.com/jpa-entities) - [JPA @Basic Annotation](https://www.baeldung.com/jpa-basic-annotation) - [Default Column Values in JPA](https://www.baeldung.com/jpa-default-column-values) +- [Persisting Enums in JPA](https://www.baeldung.com/jpa-persisting-enums-in-jpa) From 40657d8eec760c78a782e7d6e32ed8e6dfcdd162 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:18:48 -0700 Subject: [PATCH 64/74] Update README.md [skip ci] --- persistence-modules/spring-data-jpa-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index 3bd62cbd45..1f7de81c02 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -12,3 +12,4 @@ - [Batch Insert/Update with Hibernate/JPA](https://www.baeldung.com/jpa-hibernate-batch-insert-update) - [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush) - [Derived Query Methods in Spring Data JPA Repositories](https://www.baeldung.com/spring-data-derived-queries) +- [LIKE Queries in Spring JPA Repositories](https://www.baeldung.com/spring-jpa-like-queries) From b7e27478c58e83b586fe68b2deb7a4db3eef8d44 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:21:44 -0700 Subject: [PATCH 65/74] Create README.md [skip ci] --- core-java-modules/core-java-exceptions/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java-exceptions/README.md diff --git a/core-java-modules/core-java-exceptions/README.md b/core-java-modules/core-java-exceptions/README.md new file mode 100644 index 0000000000..5338789a2f --- /dev/null +++ b/core-java-modules/core-java-exceptions/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Will an Error Be Caught by Catch Block in Java?](https://www.baeldung.com/java-error-catch) From 76bc107d24e477d7b66c8219dac98a814a810047 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:22:40 -0700 Subject: [PATCH 66/74] Create README.md [skip ci] --- spf4j/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 spf4j/README.md diff --git a/spf4j/README.md b/spf4j/README.md new file mode 100644 index 0000000000..a39cd01b5e --- /dev/null +++ b/spf4j/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to SPF4J](https://www.baeldung.com/spf4j) From fb162d53f3b35c4610a6c4d17b272ec67be517b9 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:30:29 -0700 Subject: [PATCH 67/74] Create README.md [skip ci] --- persistence-modules/jpa-hibernate-cascade-type/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 persistence-modules/jpa-hibernate-cascade-type/README.md diff --git a/persistence-modules/jpa-hibernate-cascade-type/README.md b/persistence-modules/jpa-hibernate-cascade-type/README.md new file mode 100644 index 0000000000..d7f3d7dd7c --- /dev/null +++ b/persistence-modules/jpa-hibernate-cascade-type/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Overview of JPA/Hibernate Cascade Types](https://www.baeldung.com/jpa-cascade-types) From eed39166724144e5bbd5f9795a6282c4ca6cae93 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 15 Jul 2019 04:31:10 -0700 Subject: [PATCH 68/74] Update README.md [skip ci] --- algorithms-miscellaneous-3/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms-miscellaneous-3/README.md b/algorithms-miscellaneous-3/README.md index 71541cd2b3..cd3711d573 100644 --- a/algorithms-miscellaneous-3/README.md +++ b/algorithms-miscellaneous-3/README.md @@ -6,4 +6,4 @@ - [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity) - [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted) - [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle) -- [A Guide to the Folding Technique](https://www.baeldung.com/folding-hashing-technique) +- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique) From fc24c7b69bbdb990089d710e8501a22905e380ac Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 15 Jul 2019 11:13:30 -0300 Subject: [PATCH 69/74] Fixed article links, previously moved to spring-boot-mvc --- spring-boot-mvc/README.md | 2 ++ spring-mvc-basics/README.md | 1 - spring-mvc-java/README.md | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-boot-mvc/README.md b/spring-boot-mvc/README.md index d5a39cdc9f..e3e3dbdb74 100644 --- a/spring-boot-mvc/README.md +++ b/spring-boot-mvc/README.md @@ -12,3 +12,5 @@ - [Setting Up Swagger 2 with a Spring REST API](http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) - [Conditionally Enable Scheduled Jobs in Spring](https://www.baeldung.com/spring-scheduled-enabled-conditionally) - [Accessing Spring MVC Model Objects in JavaScript](https://www.baeldung.com/spring-mvc-model-objects-js) +- [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) +- [Spring Bean Annotations](http://www.baeldung.com/spring-bean-annotations) diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index afb71ce63d..a54d2133e9 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -8,7 +8,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) - [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) -- [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) - [A Guide to the ViewResolver in Spring MVC](http://www.baeldung.com/spring-mvc-view-resolver-tutorial) - [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) - [Spring MVC Content Negotiation](http://www.baeldung.com/spring-mvc-content-negotiation-json-xml) diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index f12c904229..402e1c89a2 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -6,7 +6,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [Spring Bean Annotations](http://www.baeldung.com/spring-bean-annotations) - [Introduction to Pointcut Expressions in Spring](http://www.baeldung.com/spring-aop-pointcut-tutorial) - [Introduction to Advice Types in Spring](http://www.baeldung.com/spring-aop-advice-tutorial) - [Integration Testing in Spring](http://www.baeldung.com/integration-testing-in-spring) From 3150b6d4fdd133942fec71d220d6ffdbe7ac580b Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 15 Jul 2019 13:07:01 -0300 Subject: [PATCH 70/74] Moved MediaTypeNotAcceptableException article from spring-mvc-java to spring-mvc-basics module, and added test --- spring-mvc-basics/README.md | 3 +- ...tAcceptableExceptionExampleController.java | 8 +++-- ...bleExceptionControllerIntegrationTest.java | 30 +++++++++++++++++++ spring-mvc-java/README.md | 1 - 4 files changed, 37 insertions(+), 5 deletions(-) rename {spring-mvc-java => spring-mvc-basics}/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java (92%) create mode 100644 spring-mvc-basics/src/test/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionControllerIntegrationTest.java diff --git a/spring-mvc-basics/README.md b/spring-mvc-basics/README.md index a54d2133e9..b257b3587b 100644 --- a/spring-mvc-basics/README.md +++ b/spring-mvc-basics/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) - [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) - [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) -- [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) \ No newline at end of file +- [Spring MVC and the @ModelAttribute Annotation](http://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation) +- [The HttpMediaTypeNotAcceptableException in Spring MVC](http://www.baeldung.com/spring-httpmediatypenotacceptable) \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java b/spring-mvc-basics/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java similarity index 92% rename from spring-mvc-java/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java rename to spring-mvc-basics/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java index 539a6032a6..1e3591b7aa 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java +++ b/spring-mvc-basics/src/main/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionExampleController.java @@ -1,16 +1,18 @@ package com.baeldung.exception; +import java.util.Collections; +import java.util.Map; + import org.springframework.http.MediaType; import org.springframework.web.HttpMediaTypeNotAcceptableException; +import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import java.util.Collections; -import java.util.Map; - @RestController +@ControllerAdvice public class HttpMediaTypeNotAcceptableExceptionExampleController { @PostMapping(value = "/test", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) diff --git a/spring-mvc-basics/src/test/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionControllerIntegrationTest.java b/spring-mvc-basics/src/test/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionControllerIntegrationTest.java new file mode 100644 index 0000000000..797e489080 --- /dev/null +++ b/spring-mvc-basics/src/test/java/com/baeldung/exception/HttpMediaTypeNotAcceptableExceptionControllerIntegrationTest.java @@ -0,0 +1,30 @@ +package com.baeldung.exception; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; + +import org.junit.Test; +import org.junit.runner.RunWith; +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.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +@AutoConfigureMockMvc +public class HttpMediaTypeNotAcceptableExceptionControllerIntegrationTest { + + @Autowired + MockMvc mockMvc; + + @Test + public void whenHttpMediaTypeNotAcceptableExceptionTriggered_thenExceptionHandled() throws Exception { + mockMvc.perform(post("/test").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_PDF)) + .andExpect(content().string("acceptable MIME type:application/json")); + } +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 402e1c89a2..b747a6c2a3 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -16,7 +16,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Introduction to HtmlUnit](http://www.baeldung.com/htmlunit) - [Upload and Display Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) -- [The HttpMediaTypeNotAcceptableException in Spring MVC](http://www.baeldung.com/spring-httpmediatypenotacceptable) - [Spring MVC @PathVariable with a dot (.) gets truncated](http://www.baeldung.com/spring-mvc-pathvariable-dot) - [A Quick Example of Spring Websockets’ @SendToUser Annotation](http://www.baeldung.com/spring-websockets-sendtouser) - [Working with Date Parameters in Spring](https://www.baeldung.com/spring-date-parameters) From ff2988fc5107d04f3bf345dcc7d359fc51f05b1b Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 15 Jul 2019 20:02:12 -0300 Subject: [PATCH 71/74] Moved Circular Depenednecy article from spring-mvc-java to spring-core module --- spring-core/README.md | 1 + .../com/baeldung/circulardependency/CircularDependencyA.java | 0 .../com/baeldung/circulardependency/CircularDependencyB.java | 0 .../circulardependency/CircularDependencyIntegrationTest.java | 0 .../test/java/com/baeldung/circulardependency/TestConfig.java | 0 spring-mvc-java/README.md | 1 - 6 files changed, 1 insertion(+), 1 deletion(-) rename {spring-mvc-java => spring-core}/src/main/java/com/baeldung/circulardependency/CircularDependencyA.java (100%) rename {spring-mvc-java => spring-core}/src/main/java/com/baeldung/circulardependency/CircularDependencyB.java (100%) rename {spring-mvc-java => spring-core}/src/test/java/com/baeldung/circulardependency/CircularDependencyIntegrationTest.java (100%) rename {spring-mvc-java => spring-core}/src/test/java/com/baeldung/circulardependency/TestConfig.java (100%) diff --git a/spring-core/README.md b/spring-core/README.md index d542fa8ed1..74f86ef49e 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -24,3 +24,4 @@ - [What is a Spring Bean?](https://www.baeldung.com/spring-bean) - [Spring PostConstruct and PreDestroy Annotations](https://www.baeldung.com/spring-postconstruct-predestroy) - [Guice vs Spring – Dependency Injection](https://www.baeldung.com/guice-spring-dependency-injection) +- [Circular Dependencies in Spring](http://www.baeldung.com/circular-dependencies-in-spring) diff --git a/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyA.java b/spring-core/src/main/java/com/baeldung/circulardependency/CircularDependencyA.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyA.java rename to spring-core/src/main/java/com/baeldung/circulardependency/CircularDependencyA.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyB.java b/spring-core/src/main/java/com/baeldung/circulardependency/CircularDependencyB.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/circulardependency/CircularDependencyB.java rename to spring-core/src/main/java/com/baeldung/circulardependency/CircularDependencyB.java diff --git a/spring-mvc-java/src/test/java/com/baeldung/circulardependency/CircularDependencyIntegrationTest.java b/spring-core/src/test/java/com/baeldung/circulardependency/CircularDependencyIntegrationTest.java similarity index 100% rename from spring-mvc-java/src/test/java/com/baeldung/circulardependency/CircularDependencyIntegrationTest.java rename to spring-core/src/test/java/com/baeldung/circulardependency/CircularDependencyIntegrationTest.java diff --git a/spring-mvc-java/src/test/java/com/baeldung/circulardependency/TestConfig.java b/spring-core/src/test/java/com/baeldung/circulardependency/TestConfig.java similarity index 100% rename from spring-mvc-java/src/test/java/com/baeldung/circulardependency/TestConfig.java rename to spring-core/src/test/java/com/baeldung/circulardependency/TestConfig.java diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index b747a6c2a3..e67d4f30a1 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -12,7 +12,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [A Quick Guide to Spring MVC Matrix Variables](http://www.baeldung.com/spring-mvc-matrix-variables) - [Intro to WebSockets with Spring](http://www.baeldung.com/websockets-spring) - [File Upload with Spring MVC](http://www.baeldung.com/spring-file-upload) -- [Circular Dependencies in Spring](http://www.baeldung.com/circular-dependencies-in-spring) - [Introduction to HtmlUnit](http://www.baeldung.com/htmlunit) - [Upload and Display Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) From 9566b4d5e4c6686f603f370ea676c22ee653d406 Mon Sep 17 00:00:00 2001 From: Kumar Chandrakant Date: Tue, 16 Jul 2019 10:02:17 +0530 Subject: [PATCH 72/74] Mongodb morphia (#7316) * Adding source code for tutorial tracked by BAEL-2971 * Renaming Integration Test as par standard * Incorporated review comments on the article. * Moved the morphia module inside persistence-modules/java-mongodb * Deleted the module morphia. --- morphia/README.md | 3 - morphia/pom.xml | 43 ----------- morphia/src/main/resources/logback.xml | 13 ---- persistence-modules/java-mongodb/pom.xml | 71 +++++++++++-------- .../com/baeldung/morphia/domain/Author.java | 0 .../com/baeldung/morphia/domain/Book.java | 0 .../baeldung/morphia/domain/Publisher.java | 0 .../morphia/MorphiaIntegrationTest.java | 13 ++-- pom.xml | 2 - 9 files changed, 47 insertions(+), 98 deletions(-) delete mode 100644 morphia/README.md delete mode 100644 morphia/pom.xml delete mode 100644 morphia/src/main/resources/logback.xml rename {morphia => persistence-modules/java-mongodb}/src/main/java/com/baeldung/morphia/domain/Author.java (100%) rename {morphia => persistence-modules/java-mongodb}/src/main/java/com/baeldung/morphia/domain/Book.java (100%) rename {morphia => persistence-modules/java-mongodb}/src/main/java/com/baeldung/morphia/domain/Publisher.java (100%) rename {morphia => persistence-modules/java-mongodb}/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java (94%) diff --git a/morphia/README.md b/morphia/README.md deleted file mode 100644 index 008cf76c49..0000000000 --- a/morphia/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: - -- [Intro to Morphia](http://www.baeldung.com/intro-to-morphia) diff --git a/morphia/pom.xml b/morphia/pom.xml deleted file mode 100644 index e4010a26a1..0000000000 --- a/morphia/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 4.0.0 - com.baeldung.morphia - morphia - morphia - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - .. - - - - - dev.morphia.morphia - core - ${morphia.version} - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot-maven-plugin.version} - - - - - - - 1.4.2.RELEASE - 1.5.3 - - - diff --git a/morphia/src/main/resources/logback.xml b/morphia/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/morphia/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/persistence-modules/java-mongodb/pom.xml b/persistence-modules/java-mongodb/pom.xml index dc4503c95e..35e59e60c6 100644 --- a/persistence-modules/java-mongodb/pom.xml +++ b/persistence-modules/java-mongodb/pom.xml @@ -1,40 +1,49 @@ - - 4.0.0 - com.baeldung - java-mongodb - 1.0-SNAPSHOT + + 4.0.0 + com.baeldung + java-mongodb + 1.0-SNAPSHOT java-mongodb - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - ../../ - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + - + - - de.flapdoodle.embedmongo - de.flapdoodle.embedmongo - ${flapdoodle.version} - test - - - org.mongodb - mongo-java-driver - ${mongo.version} - + + de.flapdoodle.embedmongo + de.flapdoodle.embedmongo + ${flapdoodle.version} + test + + + org.mongodb + mongo-java-driver + ${mongo.version} + - + + dev.morphia.morphia + core + ${morphia.version} + - - 1.8 - 1.8 - 3.10.1 - 1.11 - + + + + 1.8 + 1.8 + 3.10.1 + 1.11 + 1.5.3 + diff --git a/morphia/src/main/java/com/baeldung/morphia/domain/Author.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/morphia/domain/Author.java similarity index 100% rename from morphia/src/main/java/com/baeldung/morphia/domain/Author.java rename to persistence-modules/java-mongodb/src/main/java/com/baeldung/morphia/domain/Author.java diff --git a/morphia/src/main/java/com/baeldung/morphia/domain/Book.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/morphia/domain/Book.java similarity index 100% rename from morphia/src/main/java/com/baeldung/morphia/domain/Book.java rename to persistence-modules/java-mongodb/src/main/java/com/baeldung/morphia/domain/Book.java diff --git a/morphia/src/main/java/com/baeldung/morphia/domain/Publisher.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/morphia/domain/Publisher.java similarity index 100% rename from morphia/src/main/java/com/baeldung/morphia/domain/Publisher.java rename to persistence-modules/java-mongodb/src/main/java/com/baeldung/morphia/domain/Publisher.java diff --git a/morphia/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java similarity index 94% rename from morphia/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java rename to persistence-modules/java-mongodb/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java index a2542a56ab..f508c5f525 100644 --- a/morphia/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/morphia/MorphiaIntegrationTest.java @@ -2,6 +2,7 @@ package com.baeldung.morphia; import static dev.morphia.aggregation.Group.grouping; import static dev.morphia.aggregation.Group.push; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -51,8 +52,8 @@ public class MorphiaIntegrationTest { .contains("Learning Java") .find() .toList(); - assertEquals(books.size(), 1); - assertEquals(books.get(0), book); + assertEquals(1, books.size()); + assertEquals(book, books.get(0)); } @Test @@ -71,8 +72,8 @@ public class MorphiaIntegrationTest { .contains("Learning Java") .find() .toList(); - assertEquals(books.get(0) - .getCost(), 4.95); + assertEquals(4.95, books.get(0) + .getCost()); } @Test @@ -89,7 +90,7 @@ public class MorphiaIntegrationTest { .contains("Learning Java") .find() .toList(); - assertEquals(books.size(), 0); + assertEquals(0, books.size()); } @Test @@ -123,7 +124,7 @@ public class MorphiaIntegrationTest { assertEquals(books.size(), 1); assertEquals("Learning Java", books.get(0) .getTitle()); - assertEquals(null, books.get(0) + assertNull(books.get(0) .getAuthor()); } diff --git a/pom.xml b/pom.xml index 35a7b95095..05c719ec7c 100644 --- a/pom.xml +++ b/pom.xml @@ -558,7 +558,6 @@ tensorflow-java spring-boot-flowable spring-security-kerberos - morphia @@ -793,7 +792,6 @@ tensorflow-java spring-boot-flowable spring-security-kerberos - morphia From 38000941b53bb538ba9aafe321465f3a70c145ff Mon Sep 17 00:00:00 2001 From: Blake Ong Date: Tue, 16 Jul 2019 19:30:55 +0800 Subject: [PATCH 73/74] Bael 2666 concatenate strings with groovy (#7307) * BAEL-2666 code for concatenate strings with groovy * BAEL-2666 add placeholder link to readme * BAEL-2666 remove article link in README, move code to core-groovy-2 --- .../com/baeldung/concatenate/Wonder.groovy | 52 ++++++++++++++ .../concatenate/WonderUnitTest.groovy | 69 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy create mode 100644 core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy diff --git a/core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy b/core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy new file mode 100644 index 0000000000..1d7527726e --- /dev/null +++ b/core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy @@ -0,0 +1,52 @@ +package com.baeldung.concatenate + +class Wonder { + + String numOfWonder = 'seven' + + String operator_plus() { + return 'The ' + numOfWonder + ' wonders of the world' + } + + String operator_left() { + return 'The ' << numOfWonder << ' wonders of ' << 'the world' + } + + String interpolation_one() { + return "The $numOfWonder wonders of the world" + + } + + String interpolation_two() { + return "The ${numOfWonder} wonders of the world" + } + + String multilineString() { + return """ + There are $numOfWonder wonders of the world. + Can you name them all? + 1. The Great Pyramid of Giza + 2. Hanging Gardens of Babylon + 3. Colossus of Rhode + 4. Lighthouse of Alexendra + 5. Temple of Artemis + 6. Status of Zeus at Olympia + 7. Mausoleum at Halicarnassus + """ + } + + String method_concat() { + return 'The '.concat(numOfWonder).concat(' wonders of the world') + + } + + String method_builder() { + return new StringBuilder() + .append('The ').append(numOfWonder).append(' wonders of the world') + } + + String method_buffer() { + return new StringBuffer() + .append('The ').append(numOfWonder).append(' wonders of the world') + } +} \ No newline at end of file diff --git a/core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy new file mode 100644 index 0000000000..5fc74abd69 --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy @@ -0,0 +1,69 @@ +package com.baeldung.concatenate + +import org.junit.Before +import org.junit.Test + +import static org.junit.Assert.* + +class WonderUnitTest { + + static final String EXPECTED_SINGLE_LINE = "The seven wonders of the world" + + Wonder wonder + + @Before + void before() { + wonder = new Wonder() + } + + @Test + void whenUsingOperatorPlus_thenConcatCorrectly() { + assertEquals(EXPECTED_SINGLE_LINE, wonder.operator_plus()) + } + + @Test + void whenUsingOperatorLeft_thenConcatCorrectly() { + assertEquals(EXPECTED_SINGLE_LINE, wonder.operator_left()) + } + + @Test + void whenUsingInterpolationOne_thenConcatCorrectly() { + assertEquals(EXPECTED_SINGLE_LINE, wonder.interpolation_one()) + } + + @Test + void whenUsingInterpolationTwo_thenConcatCorrectly() { + assertEquals(EXPECTED_SINGLE_LINE, wonder.interpolation_two()) + } + + @Test + void whenUsingMultiline_thenConcatCorrectly() { + def expectedMultiline = """ + There are seven wonders of the world. + Can you name them all? + 1. The Great Pyramid of Giza + 2. Hanging Gardens of Babylon + 3. Colossus of Rhode + 4. Lighthouse of Alexendra + 5. Temple of Artemis + 6. Status of Zeus at Olympia + 7. Mausoleum at Halicarnassus + """ + assertEquals(expectedMultiline, wonder.multilineString()) + } + + @Test + void whenUsingMethodConcat_thenConcatCorrectly() { + assertEquals(EXPECTED_SINGLE_LINE, wonder.method_concat()) + } + + @Test + void whenUsingMethodBuilder_thenConcatCorrectly() { + assertEquals(EXPECTED_SINGLE_LINE, wonder.method_builder()) + } + + @Test + void whenUsingMethodBuffer_thenConcatCorrectly() { + assertEquals(EXPECTED_SINGLE_LINE, wonder.method_buffer()) + } +} From 01a447d6d390898f5994aa4d57276d972517d28c Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Wed, 17 Jul 2019 13:25:58 +0530 Subject: [PATCH 74/74] BAEL-15951 Moved vavr, JHipster to default profiles (#7306) --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 05c719ec7c..2e34254bf5 100644 --- a/pom.xml +++ b/pom.xml @@ -480,7 +480,6 @@ jersey JGit jgroups - jhipster jhipster-5 jib jjwt @@ -777,7 +776,6 @@ undertow - vavr vertx vertx-and-rxjava video-tutorials @@ -983,6 +981,7 @@ core-kotlin-io jenkins/hello-world + jhipster jws libraries @@ -993,6 +992,7 @@ persistence-modules/jnosql vaadin + vavr @@ -1164,7 +1164,6 @@ jersey JGit jgroups - jhipster jhipster-5 jib jjwt @@ -1443,7 +1442,6 @@ undertow - vavr vertx vertx-and-rxjava video-tutorials @@ -1495,6 +1493,7 @@ core-kotlin-2 jenkins/hello-world + jhipster jws libraries @@ -1505,6 +1504,7 @@ persistence-modules/jnosql vaadin + vavr