From a41309f4c65af08cf0bd609388d2bb59810808f1 Mon Sep 17 00:00:00 2001 From: Mateusz Szablak 'Saber-k Date: Tue, 19 Jan 2021 21:40:10 +0100 Subject: [PATCH 01/70] [BAEL-4214] Converting java.util.Properties to HashMap --- .../core-java-collections-maps-3/pom.xml | 4 + .../PropertiesToHashMapConverter.java | 39 ++++ .../PropertiesToHashMapConverterUnitTest.java | 192 ++++++++++++++++++ .../src/test/resources/toHashMap.properties | 3 + 4 files changed, 238 insertions(+) create mode 100644 core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties diff --git a/core-java-modules/core-java-collections-maps-3/pom.xml b/core-java-modules/core-java-collections-maps-3/pom.xml index 577ad58255..2561f891f1 100644 --- a/core-java-modules/core-java-collections-maps-3/pom.xml +++ b/core-java-modules/core-java-collections-maps-3/pom.xml @@ -20,6 +20,10 @@ jmh-core ${jmh-core.version} + + com.google.guava + guava + diff --git a/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java new file mode 100644 index 0000000000..2f333638a9 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java @@ -0,0 +1,39 @@ +package com.baeldung.map.propertieshashmap; + +import com.google.common.collect.Maps; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; + +public class PropertiesToHashMapConverter { + + @SuppressWarnings({"rawtypes", "unchecked"}) + public static HashMap typeCastConvert(Properties prop) { + Map step1 = prop; + Map step2 = (Map) step1; + return new HashMap<>(step2); + } + + public static HashMap loopConvert(Properties prop) { + HashMap retMap = new HashMap<>(); + for (Map.Entry entry : prop.entrySet()) { + retMap.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())); + } + return retMap; + } + + public static HashMap streamConvert(Properties prop) { + return prop.entrySet().stream().collect( + Collectors.toMap( + e -> String.valueOf(e.getKey()), + e -> String.valueOf(e.getValue()), + (prev, next) -> next, HashMap::new + )); + } + + public static HashMap guavaConvert(Properties prop) { + return Maps.newHashMap(Maps.fromProperties(prop)); + } +} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java new file mode 100644 index 0000000000..b1370dcfbf --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java @@ -0,0 +1,192 @@ +package com.baeldung.map.propertieshashmap; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.*; + +class PropertiesToHashMapConverterUnitTest { + + private Properties properties; + + private final static String propertyFileName = "toHashMap.properties"; + + @BeforeEach + public void setup() throws IOException { + properties = new Properties(); + try (InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName)) { + if (is != null) { + properties.load(is); + } + } + } + + @Test + public void havingPropertiesLoaded_whenCheck_thenEquals() { + assertEquals(3, properties.size()); + assertEquals("str_value", properties.get("property1")); + assertEquals("123", properties.get("property2")); + assertEquals("", properties.get("property3")); + } + + @Test + public void whenPropertiesModified_thenTypeSafeIssues() { + compromiseProperties(properties); + + assertEquals(5, properties.size()); + + assertNull(properties.getProperty("property4")); + assertNotEquals(String.class, properties.get("property4").getClass()); + assertEquals(456, properties.get("property4")); + + + assertNull(properties.getProperty("5")); + assertNotEquals(String.class, properties.get(5).getClass()); + assertEquals(10.11, properties.get(5)); + } + + @Test + public void havingNonModifiedProperties_whenTypeCastConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.typeCastConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenTypeCastConvert_thenClassCastException() { + compromiseProperties(properties); + HashMap hMap = PropertiesToHashMapConverter.typeCastConvert(properties); + assertEquals(5, hMap.size()); + + assertThrows(ClassCastException.class, () -> { + String s = hMap.get("property4"); + }); + assertEquals(Integer.class, ((Object) hMap.get("property4")).getClass()); + + assertNull(hMap.get("5")); + assertNotNull(hMap.get(5)); + assertThrows(ClassCastException.class, () -> { + String s = hMap.get(5); + }); + assertEquals(Double.class, ((Object) hMap.get(5)).getClass()); + } + + @Test + public void havingNonModifiedProperties_whenLoopConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.loopConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenLoopConvert_thenNoClassCastException() { + compromiseProperties(properties); + HashMap hMap = PropertiesToHashMapConverter.loopConvert(properties); + assertEquals(5, hMap.size()); + + assertDoesNotThrow(() -> { + String s = hMap.get("property4"); + }); + assertEquals(String.class, hMap.get("property4").getClass()); + assertEquals("456", hMap.get("property4")); + + assertDoesNotThrow(() -> { + String s = hMap.get("5"); + }); + assertEquals("10.11", hMap.get("5")); + } + + @Test + public void havingNonModifiedProperties_whenStreamConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.streamConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenStreamConvert_thenNoClassCastException() { + compromiseProperties(properties); + HashMap hMap = PropertiesToHashMapConverter.streamConvert(properties); + assertEquals(5, hMap.size()); + + assertDoesNotThrow(() -> { + String s = hMap.get("property4"); + }); + assertEquals(String.class, hMap.get("property4").getClass()); + assertEquals("456", hMap.get("property4")); + + assertDoesNotThrow(() -> { + String s = hMap.get("5"); + }); + assertEquals("10.11", hMap.get("5")); + } + + @Test + public void havingModifiedProperties_whenLoopConvertAndStreamConvert_thenHashMapsSame() { + compromiseProperties(properties); + HashMap hMap1 = PropertiesToHashMapConverter.loopConvert(properties); + HashMap hMap2 = PropertiesToHashMapConverter.streamConvert(properties); + + assertEquals(hMap2, hMap1); + } + + @Test + public void havingNonModifiedProperties_whenGuavaConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.guavaConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenGuavaConvert_thenUnableToConvertAndThrowException() { + compromiseProperties(properties); + assertThrows(Exception.class, () -> PropertiesToHashMapConverter.guavaConvert(properties)); + } + + @Test + public void havingModifiedPropertiesWithNoIntegerValue_whenGuavaConvert_thenNullPointerException() { + properties.put("property4", 456); + assertThrows(NullPointerException.class, () -> PropertiesToHashMapConverter.guavaConvert(properties)); + } + + @Test + public void havingModifiedPropertiesWithNoIntegerKey_whenGuavaConvert_thenClassCastException() { + properties.put(5, 10.11); + assertThrows(ClassCastException.class, () -> PropertiesToHashMapConverter.guavaConvert(properties)); + } + + + private void compromiseProperties(Properties prop) { + prop.put("property4", 456); + prop.put(5, 10.11); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties b/core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties new file mode 100644 index 0000000000..b731aa94bb --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties @@ -0,0 +1,3 @@ +property1=str_value +property2=123 +property3= \ No newline at end of file From 27c423c4e026c02395059c7a41e31782e514da73 Mon Sep 17 00:00:00 2001 From: Mateusz Szablak 'Saber-k Date: Tue, 19 Jan 2021 21:40:10 +0100 Subject: [PATCH 02/70] [BAEL-4214] Converting java.util.Properties to HashMap --- .../core-java-collections-maps-3/pom.xml | 4 + .../PropertiesToHashMapConverter.java | 39 ++++ .../PropertiesToHashMapConverterUnitTest.java | 192 ++++++++++++++++++ .../src/test/resources/toHashMap.properties | 3 + 4 files changed, 238 insertions(+) create mode 100644 core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java create mode 100644 core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties diff --git a/core-java-modules/core-java-collections-maps-3/pom.xml b/core-java-modules/core-java-collections-maps-3/pom.xml index 577ad58255..2561f891f1 100644 --- a/core-java-modules/core-java-collections-maps-3/pom.xml +++ b/core-java-modules/core-java-collections-maps-3/pom.xml @@ -20,6 +20,10 @@ jmh-core ${jmh-core.version} + + com.google.guava + guava + diff --git a/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java new file mode 100644 index 0000000000..2f333638a9 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java @@ -0,0 +1,39 @@ +package com.baeldung.map.propertieshashmap; + +import com.google.common.collect.Maps; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; + +public class PropertiesToHashMapConverter { + + @SuppressWarnings({"rawtypes", "unchecked"}) + public static HashMap typeCastConvert(Properties prop) { + Map step1 = prop; + Map step2 = (Map) step1; + return new HashMap<>(step2); + } + + public static HashMap loopConvert(Properties prop) { + HashMap retMap = new HashMap<>(); + for (Map.Entry entry : prop.entrySet()) { + retMap.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())); + } + return retMap; + } + + public static HashMap streamConvert(Properties prop) { + return prop.entrySet().stream().collect( + Collectors.toMap( + e -> String.valueOf(e.getKey()), + e -> String.valueOf(e.getValue()), + (prev, next) -> next, HashMap::new + )); + } + + public static HashMap guavaConvert(Properties prop) { + return Maps.newHashMap(Maps.fromProperties(prop)); + } +} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java new file mode 100644 index 0000000000..1985fbe673 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverterUnitTest.java @@ -0,0 +1,192 @@ +package com.baeldung.map.propertieshashmap; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.*; + +class PropertiesToHashMapConverterUnitTest { + + private Properties properties; + + private final static String propertyFileName = "toHashMap.properties"; + + @BeforeEach + public void setup() throws IOException { + properties = new Properties(); + try (InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName)) { + if (is != null) { + properties.load(is); + } + } + } + + @Test + public void havingPropertiesLoaded_whenCheck_thenEquals() { + assertEquals(3, properties.size()); + assertEquals("str_value", properties.get("property1")); + assertEquals("123", properties.get("property2")); + assertEquals("", properties.get("property3")); + } + + @Test + public void whenPropertiesModified_thenTypeSafeIssues() { + compromiseProperties(properties); + + assertEquals(5, properties.size()); + + assertNull(properties.getProperty("property4")); + assertNotEquals(String.class, properties.get("property4").getClass()); + assertEquals(456, properties.get("property4")); + + + assertNull(properties.getProperty("5")); + assertNotEquals(String.class, properties.get(5).getClass()); + assertEquals(10.11, properties.get(5)); + } + + @Test + public void havingNonModifiedProperties_whenTypeCastConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.typeCastConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenTypeCastConvert_thenClassCastException() { + compromiseProperties(properties); + HashMap hMap = PropertiesToHashMapConverter.typeCastConvert(properties); + assertEquals(5, hMap.size()); + + assertThrows(ClassCastException.class, () -> { + String s = hMap.get("property4"); + }); + assertEquals(Integer.class, ((Object) hMap.get("property4")).getClass()); + + assertNull(hMap.get("5")); + assertNotNull(hMap.get(5)); + assertThrows(ClassCastException.class, () -> { + String s = hMap.get(5); + }); + assertEquals(Double.class, ((Object) hMap.get(5)).getClass()); + } + + @Test + public void havingNonModifiedProperties_whenLoopConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.loopConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenLoopConvert_thenNoClassCastException() { + compromiseProperties(properties); + HashMap hMap = PropertiesToHashMapConverter.loopConvert(properties); + assertEquals(5, hMap.size()); + + assertDoesNotThrow(() -> { + String s = hMap.get("property4"); + }); + assertEquals(String.class, hMap.get("property4").getClass()); + assertEquals("456", hMap.get("property4")); + + assertDoesNotThrow(() -> { + String s = hMap.get("5"); + }); + assertEquals("10.11", hMap.get("5")); + } + + @Test + public void havingNonModifiedProperties_whenStreamConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.streamConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenStreamConvert_thenNoClassCastException() { + compromiseProperties(properties); + HashMap hMap = PropertiesToHashMapConverter.streamConvert(properties); + assertEquals(5, hMap.size()); + + assertDoesNotThrow(() -> { + String s = hMap.get("property4"); + }); + assertEquals(String.class, hMap.get("property4").getClass()); + assertEquals("456", hMap.get("property4")); + + assertDoesNotThrow(() -> { + String s = hMap.get("5"); + }); + assertEquals("10.11", hMap.get("5")); + } + + @Test + public void havingModifiedProperties_whenLoopConvertAndStreamConvert_thenHashMapsSame() { + compromiseProperties(properties); + HashMap hMap1 = PropertiesToHashMapConverter.loopConvert(properties); + HashMap hMap2 = PropertiesToHashMapConverter.streamConvert(properties); + + assertEquals(hMap2, hMap1); + } + + @Test + public void havingNonModifiedProperties_whenGuavaConvert_thenNoTypeSafeIssues() { + HashMap hMap = PropertiesToHashMapConverter.guavaConvert(properties); + + assertEquals(3, hMap.size()); + assertEquals(String.class, hMap.get("property1").getClass()); + assertEquals(properties.get("property1"), hMap.get("property1")); + assertEquals(String.class, hMap.get("property2").getClass()); + assertEquals(properties.get("property2"), hMap.get("property2")); + assertEquals(String.class, hMap.get("property3").getClass()); + assertEquals(properties.get("property3"), hMap.get("property3")); + } + + @Test + public void havingModifiedProperties_whenGuavaConvert_thenUnableToConvertAndThrowException() { + compromiseProperties(properties); + assertThrows(Exception.class, () -> PropertiesToHashMapConverter.guavaConvert(properties)); + } + + @Test + public void havingModifiedPropertiesWithNoIntegerValue_whenGuavaConvert_thenNullPointerException() { + properties.put("property4", 456); + assertThrows(NullPointerException.class, () -> PropertiesToHashMapConverter.guavaConvert(properties)); + } + + @Test + public void havingModifiedPropertiesWithNoIntegerKey_whenGuavaConvert_thenClassCastException() { + properties.put(5, 10.11); + assertThrows(ClassCastException.class, () -> PropertiesToHashMapConverter.guavaConvert(properties)); + } + + + private void compromiseProperties(Properties prop) { + prop.put("property4", 456); + prop.put(5, 10.11); + } +} diff --git a/core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties b/core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties new file mode 100644 index 0000000000..727e858a8c --- /dev/null +++ b/core-java-modules/core-java-collections-maps-3/src/test/resources/toHashMap.properties @@ -0,0 +1,3 @@ +property1=str_value +property2=123 +property3= From 6a2d8b85ef070c8b3a56801f227e019f2f9a005a Mon Sep 17 00:00:00 2001 From: Simone Cusimano Date: Mon, 25 Jan 2021 20:10:11 +0100 Subject: [PATCH 03/70] Add two modules for BAEL-4688 --- .../spring-boot-jersey/build.gradle | 22 +++ .../gradle/wrapper/gradle-wrapper.properties | 5 + .../spring-boot-jersey/gradlew | 184 ++++++++++++++++++ .../spring-boot-jersey/gradlew.bat | 89 +++++++++ .../spring-boot-jersey/settings.gradle | 1 + .../boot/jersey/JerseyApplication.java | 13 ++ .../jersey/controllers/HelloController.java | 22 +++ .../src/main/resources/application.properties | 1 + .../JerseyApplicationIntegrationTests.java | 13 ++ .../controllers/HelloControllerUnitTest.java | 27 +++ .../spring-boot-mvc/build.gradle | 22 +++ .../gradle/wrapper/gradle-wrapper.properties | 5 + .../spring-boot-mvc/gradlew | 184 ++++++++++++++++++ .../spring-boot-mvc/gradlew.bat | 89 +++++++++ .../spring-boot-mvc/settings.gradle | 1 + .../com/baeldung/boot/mvc/MvcApplication.java | 13 ++ .../boot/mvc/controllers/HelloController.java | 21 ++ .../src/main/resources/application.properties | 1 + .../mvc/MvcApplicationIntegrationTests.java | 13 ++ .../controllers/HelloControllerUnitTest.java | 27 +++ 20 files changed, 753 insertions(+) create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/JerseyApplication.java create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/resources/application.properties create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/JerseyApplicationIntegrationTests.java create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/MvcApplication.java create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/controllers/HelloController.java create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/resources/application.properties create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/MvcApplicationIntegrationTests.java create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle new file mode 100644 index 0000000000..e906adec44 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'org.springframework.boot' version '2.4.2' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' +} + +group = 'com.baeldung.boot' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '15' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-jersey' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +test { + useJUnitPlatform() +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..4d9ca16491 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew new file mode 100644 index 0000000000..8f8904743c --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew @@ -0,0 +1,184 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ]; do + ls=$(ls -ld "$PRG") + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then + PRG="$link" + else + PRG=$(dirname "$PRG")"/$link" + fi +done +SAVED="$(pwd)" +cd "$(dirname \"$PRG\")/" >/dev/null +APP_HOME="$(pwd -P)" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=$(basename "$0") + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn() { + echo "$*" +} + +die() { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$(uname)" in +CYGWIN*) + cygwin=true + ;; +Darwin*) + darwin=true + ;; +MINGW*) + msys=true + ;; +NONSTOP*) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ]; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then + MAX_FD_LIMIT=$(ulimit -H -n) + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; then + APP_HOME=$(cygpath --path --mixed "$APP_HOME") + CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") + + JAVACMD=$(cygpath --unix "$JAVACMD") + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) + SEP="" + for dir in $ROOTDIRSRAW; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ]; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@"; do + CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) + CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition + eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") + else + eval $(echo args$i)="\"$arg\"" + fi + i=$(expr $i + 1) + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save() { + for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat new file mode 100644 index 0000000000..107acd32c4 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle new file mode 100644 index 0000000000..5ce50b489f --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'jersey' diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/JerseyApplication.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/JerseyApplication.java new file mode 100644 index 0000000000..b8ee0d0115 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/JerseyApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.boot.jersey; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JerseyApplication { + + public static void main(String[] args) { + SpringApplication.run(JerseyApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java new file mode 100644 index 0000000000..2167031f12 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java @@ -0,0 +1,22 @@ +package com.baeldung.boot.jersey.controllers; + +import java.awt.PageAttributes.MediaType; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.xml.ws.Response; + +@Path("/hello") +public class HelloController { + + @GET + @Path("/{name}") + @Produces(MediaType.TEXT_PLAIN) + public Response hello(@PathParam("name") String name) { + return Response.ok("Hello, " + name) + .build(); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/resources/application.properties b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/JerseyApplicationIntegrationTests.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/JerseyApplicationIntegrationTests.java new file mode 100644 index 0000000000..9bd6bbf029 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/JerseyApplicationIntegrationTests.java @@ -0,0 +1,13 @@ +package com.baeldung.boot.jersey; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class JerseyApplicationIntegrationTests { + + @Test + void contextLoads() { + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java new file mode 100644 index 0000000000..9e18d35cec --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.boot.jersey.controllers; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import javax.xml.ws.Response; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@Import(HelloController.class) +@ExtendWith(SpringExtension.class) +public class HelloControllerUnitTest { + + @Autowired + private HelloController helloController; + + @Test + public void helloTest() { + Response response = this.helloController.hello("Caio"); + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getEntity()).isEqualTo("Hello, Caio"); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle new file mode 100644 index 0000000000..577ce18653 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'org.springframework.boot' version '2.4.2' + id 'io.spring.dependency-management' version '1.0.11.RELEASE' + id 'java' +} + +group = 'com.baeldung.boot' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '15' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +test { + useJUnitPlatform() +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..4d9ca16491 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew new file mode 100644 index 0000000000..8f8904743c --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew @@ -0,0 +1,184 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ]; do + ls=$(ls -ld "$PRG") + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then + PRG="$link" + else + PRG=$(dirname "$PRG")"/$link" + fi +done +SAVED="$(pwd)" +cd "$(dirname \"$PRG\")/" >/dev/null +APP_HOME="$(pwd -P)" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=$(basename "$0") + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn() { + echo "$*" +} + +die() { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$(uname)" in +CYGWIN*) + cygwin=true + ;; +Darwin*) + darwin=true + ;; +MINGW*) + msys=true + ;; +NONSTOP*) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ]; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then + MAX_FD_LIMIT=$(ulimit -H -n) + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; then + APP_HOME=$(cygpath --path --mixed "$APP_HOME") + CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") + + JAVACMD=$(cygpath --unix "$JAVACMD") + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) + SEP="" + for dir in $ROOTDIRSRAW; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ]; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@"; do + CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) + CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition + eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") + else + eval $(echo args$i)="\"$arg\"" + fi + i=$(expr $i + 1) + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save() { + for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat new file mode 100644 index 0000000000..107acd32c4 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle new file mode 100644 index 0000000000..028442d0f5 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'mvc' diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/MvcApplication.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/MvcApplication.java new file mode 100644 index 0000000000..9c42c72fd7 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/MvcApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.boot.mvc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MvcApplication { + + public static void main(String[] args) { + SpringApplication.run(MvcApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/controllers/HelloController.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/controllers/HelloController.java new file mode 100644 index 0000000000..0b4c569ba9 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/java/com/baeldung/boot/mvc/controllers/HelloController.java @@ -0,0 +1,21 @@ +package com.baeldung.boot.mvc.controllers; + + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/hello") +public class HelloController { + + @GetMapping(value = "/{name}", produces = MediaType.TEXT_PLAIN_VALUE) + public ResponseEntity hello(@PathVariable String name) { + return new ResponseEntity<>("Hello, " + name, HttpStatus.OK); + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/resources/application.properties b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/MvcApplicationIntegrationTests.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/MvcApplicationIntegrationTests.java new file mode 100644 index 0000000000..d05cb97e47 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/MvcApplicationIntegrationTests.java @@ -0,0 +1,13 @@ +package com.baeldung.boot.mvc; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class MvcApplicationIntegrationTests { + + @Test + void contextLoads() { + } + +} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java new file mode 100644 index 0000000000..5a243347b8 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.boot.mvc.controllers; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@Import(HelloController.class) +@ExtendWith(SpringExtension.class) +public class HelloControllerUnitTest { + + @Autowired + private HelloController helloController; + + @Test + public void helloTest() { + ResponseEntity response = this.helloController.hello("Caio"); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(response.getBody()).isEqualTo("Hello, Caio"); + } + +} From c3c4dc627a325c7f5f8191e2d119cd693d8cd627 Mon Sep 17 00:00:00 2001 From: Simone Cusimano Date: Mon, 25 Jan 2021 20:16:55 +0100 Subject: [PATCH 04/70] Fix wrong imports --- .../baeldung/boot/jersey/controllers/HelloController.java | 8 +++----- .../boot/jersey/controllers/HelloControllerUnitTest.java | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java index 2167031f12..2774e458de 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/main/java/com/baeldung/boot/jersey/controllers/HelloController.java @@ -1,12 +1,11 @@ package com.baeldung.boot.jersey.controllers; -import java.awt.PageAttributes.MediaType; - import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.xml.ws.Response; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; @Path("/hello") public class HelloController { @@ -15,8 +14,7 @@ public class HelloController { @Path("/{name}") @Produces(MediaType.TEXT_PLAIN) public Response hello(@PathParam("name") String name) { - return Response.ok("Hello, " + name) - .build(); + return Response.ok("Hello, " + name).build(); } } diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java index 9e18d35cec..81ec381f2c 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java @@ -1,8 +1,8 @@ package com.baeldung.boot.jersey.controllers; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import javax.ws.rs.core.Response; -import javax.xml.ws.Response; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; From caf864b8e79965ac0195a697acb4e65d1257f583 Mon Sep 17 00:00:00 2001 From: vishal Date: Mon, 1 Feb 2021 23:19:23 +0100 Subject: [PATCH 05/70] BAEL-2620 | Update test with latest version of Spring 5 and JUnit 5 --- .../GreetControllerIntegrationTest.java | 47 ++++++++++--------- .../GreetControllerRealIntegrationTest.java | 20 +++----- .../controller/GreetControllerUnitTest.java | 25 +++++----- 3 files changed, 43 insertions(+), 49 deletions(-) diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java index 3d34a46791..7b9da5707d 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java @@ -1,17 +1,13 @@ package com.baeldung.web.controller; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; - -import javax.servlet.ServletContext; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import com.baeldung.spring.web.config.WebConfig; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -20,31 +16,34 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import com.baeldung.spring.web.config.WebConfig; +import javax.servlet.ServletContext; -@RunWith(SpringJUnit4ClassRunner.class) +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {WebConfig.class}) @WebAppConfiguration -@ContextConfiguration(classes = { WebConfig.class, WebConfig.class }) public class GreetControllerIntegrationTest { @Autowired - private WebApplicationContext wac; + private WebApplicationContext webApplicationContext; private MockMvc mockMvc; private static final String CONTENT_TYPE = "application/json"; - @Before - public void setup() throws Exception { - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + @BeforeEach + public void setup() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build(); } @Test public void givenWac_whenServletContext_thenItProvidesGreetController() { - final ServletContext servletContext = wac.getServletContext(); - Assert.assertNotNull(servletContext); - Assert.assertTrue(servletContext instanceof MockServletContext); - Assert.assertNotNull(wac.getBean("greetController")); + final ServletContext servletContext = webApplicationContext.getServletContext(); + assertNotNull(servletContext); + assertTrue(servletContext instanceof MockServletContext); + assertNotNull(webApplicationContext.getBean("greetController")); } @Test @@ -54,8 +53,12 @@ public class GreetControllerIntegrationTest { @Test public void givenGreetURI_whenMockMVC_thenVerifyResponse() throws Exception { - final MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.get("/greet")).andDo(print()).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Hello World!!!")).andReturn(); - Assert.assertEquals(CONTENT_TYPE, mvcResult.getResponse().getContentType()); + final MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.get("/greet")) + .andDo(print()) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Hello World!!!")) + .andReturn(); + assertEquals(CONTENT_TYPE, mvcResult.getResponse().getContentType()); } @Test diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java index 05c6313e76..36751ba883 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java @@ -2,33 +2,27 @@ package com.baeldung.web.controller; import io.restassured.RestAssured; import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; +import static io.restassured.RestAssured.DEFAULT_PORT; import static io.restassured.RestAssured.given; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT) +@SpringBootTest(webEnvironment = DEFINED_PORT) @TestPropertySource(properties = {"spring.main.allow-bean-definition-overriding=true", "server.servlet.context-path=/"}) public class GreetControllerRealIntegrationTest { - @LocalServerPort - private int port; - @Before public void setUp() { - RestAssured.port = port; + RestAssured.port = DEFAULT_PORT; } @Test public void givenGreetURI_whenSendingReq_thenVerifyResponse() { given().get("/greet") - .then() - .statusCode(200); + .then() + .statusCode(200); } } diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java index eacd256438..ecc55e8da2 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java @@ -1,25 +1,22 @@ 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.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -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.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +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.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + public class GreetControllerUnitTest { private MockMvc mockMvc; private static final String CONTENT_TYPE = "application/json"; - @Before - public void setup() { + @BeforeEach + void setUp() { this.mockMvc = MockMvcBuilders.standaloneSetup(new GreetController()).build(); } @@ -50,12 +47,12 @@ public class GreetControllerUnitTest { @Test public void givenGreetURIWithPost_whenMockMVC_thenVerifyResponse() throws Exception { - this.mockMvc.perform(MockMvcRequestBuilders.post("/greetWithPost")).andDo(print()).andExpect(status().isOk()).andExpect(content().contentType(CONTENT_TYPE)).andExpect(jsonPath("$.message").value("Hello World!!!")); + this.mockMvc.perform(post("/greetWithPost")).andDo(print()).andExpect(status().isOk()).andExpect(content().contentType(CONTENT_TYPE)).andExpect(jsonPath("$.message").value("Hello World!!!")); } @Test public void givenGreetURIWithPostAndFormData_whenMockMVC_thenVerifyResponse() throws Exception { - this.mockMvc.perform(MockMvcRequestBuilders.post("/greetWithPostAndFormData").param("id", "1").param("name", "John Doe")).andDo(print()).andExpect(status().isOk()).andExpect(content().contentType(CONTENT_TYPE)) + this.mockMvc.perform(post("/greetWithPostAndFormData").param("id", "1").param("name", "John Doe")).andDo(print()).andExpect(status().isOk()).andExpect(content().contentType(CONTENT_TYPE)) .andExpect(jsonPath("$.message").value("Hello World John Doe!!!")).andExpect(jsonPath("$.id").value(1)); } } From aa69c77efaa4c21309e95b8a727033ad0872e67f Mon Sep 17 00:00:00 2001 From: Simone Cusimano Date: Wed, 3 Feb 2021 19:37:36 +0100 Subject: [PATCH 06/70] Refactor unit test methods name --- .../boot/jersey/controllers/HelloControllerUnitTest.java | 2 +- .../baeldung/boot/mvc/controllers/HelloControllerUnitTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java index 81ec381f2c..e0c48da5bd 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/src/test/java/com/baeldung/boot/jersey/controllers/HelloControllerUnitTest.java @@ -18,7 +18,7 @@ public class HelloControllerUnitTest { private HelloController helloController; @Test - public void helloTest() { + public void whenHelloIsInvokedWithCaio_thenReturn200AsStatusAndHelloCaioAsBody() { Response response = this.helloController.hello("Caio"); assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getEntity()).isEqualTo("Hello, Caio"); diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java index 5a243347b8..3bef9df4fd 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/src/test/java/com/baeldung/boot/mvc/controllers/HelloControllerUnitTest.java @@ -18,7 +18,7 @@ public class HelloControllerUnitTest { private HelloController helloController; @Test - public void helloTest() { + public void whenHelloIsInvokedWithCaio_thenReturn200AsStatusAndHelloCaioAsBody() { ResponseEntity response = this.helloController.hello("Caio"); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(response.getBody()).isEqualTo("Hello, Caio"); From 4f0173ebae5eb50b8f5423f6501dbd291e6df7f9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:08:46 +0800 Subject: [PATCH 07/70] Update README.md --- spring-web-modules/spring-resttemplate-2/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-web-modules/spring-resttemplate-2/README.md b/spring-web-modules/spring-resttemplate-2/README.md index 54fad5e01b..ace7ae817b 100644 --- a/spring-web-modules/spring-resttemplate-2/README.md +++ b/spring-web-modules/spring-resttemplate-2/README.md @@ -10,5 +10,4 @@ This module contains articles about Spring RestTemplate - [RestTemplate Post Request with JSON](https://www.baeldung.com/spring-resttemplate-post-json) - [How to Compress Requests Using the Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-compressing-requests) - [Get list of JSON objects with Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-json-list) -- [A Guide To Spring Redirects](https://www.baeldung.com/spring-redirect-and-forward) - [Spring RestTemplate Exception: “Not enough variables available to expand”](https://www.baeldung.com/spring-not-enough-variables-available) From 9ed2982f8f0d9691dcc0ad7366cb1d94b456286a Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:12:06 +0800 Subject: [PATCH 08/70] Update README.md --- spring-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-5/README.md b/spring-5/README.md index cce18bedf8..845d602480 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -11,3 +11,4 @@ This module contains articles about Spring 5 - [Spring Assert Statements](https://www.baeldung.com/spring-assert) - [Difference between \ vs \](https://www.baeldung.com/spring-contextannotation-contextcomponentscan) - [Finding the Spring Version](https://www.baeldung.com/spring-find-version) +- [Spring 5 Testing with @EnabledIf Annotation](https://www.baeldung.com/spring-5-enabledIf) From 59da123a98e892e10eea60c2580a367ef76d1d85 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:15:15 +0800 Subject: [PATCH 09/70] Create README.md --- spring-5/src/test/java/com/baeldung/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 spring-5/src/test/java/com/baeldung/README.md diff --git a/spring-5/src/test/java/com/baeldung/README.md b/spring-5/src/test/java/com/baeldung/README.md new file mode 100644 index 0000000000..0ff61914d5 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Concurrent Test Execution in Spring 5](https://www.baeldung.com/spring-5-concurrent-tests) From 944c965952a4a06f9b5663961927303c6a0213f7 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:17:27 +0800 Subject: [PATCH 10/70] Update README.md --- core-java-modules/core-java-lang-math-3/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index dda3013407..1dd3a3c7e0 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -4,6 +4,5 @@ ### Relevant articles: -- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial) - [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) From 9e867ffc0d35523c5a7ea8b9a2b7e57f6ad00cab Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:20:19 +0800 Subject: [PATCH 11/70] Update README.md --- spring-boot-modules/spring-boot-data-2/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-data-2/README.md b/spring-boot-modules/spring-boot-data-2/README.md index c21ce02a2e..d5020ce354 100644 --- a/spring-boot-modules/spring-boot-data-2/README.md +++ b/spring-boot-modules/spring-boot-data-2/README.md @@ -1,4 +1,3 @@ ### Relevant Articles: - [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper) -- [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) From 43efec8e232a3450cf5c8f3dcbe3912ec223594c Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:44:24 +0800 Subject: [PATCH 12/70] Update README.md --- spring-web-modules/spring-mvc-basics-4/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-mvc-basics-4/README.md b/spring-web-modules/spring-mvc-basics-4/README.md index d0bca4a303..211564a363 100644 --- a/spring-web-modules/spring-mvc-basics-4/README.md +++ b/spring-web-modules/spring-mvc-basics-4/README.md @@ -5,7 +5,7 @@ The "REST With Spring" Classes: https://bit.ly/restwithspring ### Relevant Articles: - [Quick Guide to Spring Controllers](https://www.baeldung.com/spring-controllers) -- [Model, ModelMap, and ModelView in Spring MVC](https://www.baeldung.com/spring-mvc-model-model-map-model-view) +- [Model, ModelMap, and ModelAndView in Spring MVC](https://www.baeldung.com/spring-mvc-model-model-map-model-view) - [Spring Web Contexts](https://www.baeldung.com/spring-web-contexts) - [Spring Optional Path variables](https://www.baeldung.com/spring-optional-path-variables) - [JSON Parameters with Spring MVC](https://www.baeldung.com/spring-mvc-send-json-parameters) From 5ab8f0678f06deeca9e494af1e5abcedc958d8a1 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:46:38 +0800 Subject: [PATCH 13/70] Update README.md --- core-java-modules/core-java-9-new-features/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-9-new-features/README.md b/core-java-modules/core-java-9-new-features/README.md index 5af069c6f0..4045a37d9d 100644 --- a/core-java-modules/core-java-9-new-features/README.md +++ b/core-java-modules/core-java-9-new-features/README.md @@ -4,7 +4,7 @@ This module contains articles about core Java features that have been introduced ### Relevant Articles: -- [Java 9 New Features](https://www.baeldung.com/new-java-9) +- [New Features in Java 9](https://www.baeldung.com/new-java-9) - [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles) - [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client) - [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar) From d9fcd0de3451076224819b2946207f66729ee723 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:49:18 +0800 Subject: [PATCH 14/70] Update README.md --- core-java-modules/core-java-10/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-10/README.md b/core-java-modules/core-java-10/README.md index 38b1db1c05..11c2051816 100644 --- a/core-java-modules/core-java-10/README.md +++ b/core-java-modules/core-java-10/README.md @@ -5,7 +5,7 @@ This module contains articles about Java 10 core features ### Relevant Articles: - [Java 10 LocalVariable Type-Inference](http://www.baeldung.com/java-10-local-variable-type-inference) -- [Guide to Java 10](http://www.baeldung.com/java-10-overview) +- [New Features in Java 10](https://www.baeldung.com/java-10-overview) - [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another) - [Deep Dive Into the New Java JIT Compiler – Graal](https://www.baeldung.com/graal-java-jit-compiler) - [Copying Sets in Java](https://www.baeldung.com/java-copy-sets) From 0e93e2f779c2ca47b4ca1f474ec01724e6e50614 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:52:55 +0800 Subject: [PATCH 15/70] Update README.md --- core-java-modules/core-java-13/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-13/README.md b/core-java-modules/core-java-13/README.md index 697f89c362..9215139dd4 100644 --- a/core-java-modules/core-java-13/README.md +++ b/core-java-modules/core-java-13/README.md @@ -1,4 +1,4 @@ ### Relevant articles: - [Java Switch Statement](https://www.baeldung.com/java-switch) -- [New Java 13 Features](https://www.baeldung.com/java-13-new-features) +- [New Features in Java 13](https://www.baeldung.com/java-13-new-features) From 25d4cd922284b3db470d761013699f67d4352552 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:55:38 +0800 Subject: [PATCH 16/70] Update README.md --- core-java-modules/core-java-12/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core-java-modules/core-java-12/README.md b/core-java-modules/core-java-12/README.md index c28df26c6f..b509be876c 100644 --- a/core-java-modules/core-java-12/README.md +++ b/core-java-modules/core-java-12/README.md @@ -1,5 +1,4 @@ ## Relevant Articles: - - [String API Updates in Java 12](https://www.baeldung.com/java12-string-api) -- [Java 12 New Features](https://www.baeldung.com/java-12-new-features) +- [New Features in Java 12](https://www.baeldung.com/java-12-new-features) From 15d247be80f9563d13f31ed90ce8ffa5835e4186 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:59:24 +0800 Subject: [PATCH 17/70] Update README.md --- core-java-modules/core-java-char/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-char/README.md b/core-java-modules/core-java-char/README.md index fd79da15ab..5f33aa6914 100644 --- a/core-java-modules/core-java-char/README.md +++ b/core-java-modules/core-java-char/README.md @@ -3,4 +3,4 @@ This module contains articles about Java Character Class ### Relevant Articles: -- [Character#isAlphabetic vs Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic) +- [Character#isAlphabetic vs. Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic) From 5d2087c7116212cfe9fc6de91b3d5e814e7181df Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 02:04:28 +0800 Subject: [PATCH 18/70] Update README.md --- core-java-modules/core-java-14/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-14/README.md b/core-java-modules/core-java-14/README.md index 004b3587c4..07cdf9859c 100644 --- a/core-java-modules/core-java-14/README.md +++ b/core-java-modules/core-java-14/README.md @@ -10,4 +10,4 @@ This module contains articles about Java 14. - [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception) - [Foreign Memory Access API in Java 14](https://www.baeldung.com/java-foreign-memory-access) - [Java 14 Record Keyword](https://www.baeldung.com/java-record-keyword) -- [Java 14 – New Features](https://www.baeldung.com/java-14-new-features) +- [New Features in Java 14](https://www.baeldung.com/java-14-new-features) From e043ad6d20efa7f574744672c663ad004b139dd9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 02:19:55 +0800 Subject: [PATCH 19/70] Update README.md --- spring-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-5/README.md b/spring-5/README.md index 845d602480..2ddd9fa94f 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -12,3 +12,4 @@ This module contains articles about Spring 5 - [Difference between \ vs \](https://www.baeldung.com/spring-contextannotation-contextcomponentscan) - [Finding the Spring Version](https://www.baeldung.com/spring-find-version) - [Spring 5 Testing with @EnabledIf Annotation](https://www.baeldung.com/spring-5-enabledIf) +- [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) From 5ae0cce72e3ab250455b3c4bfdb5dcc033f24d27 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 02:25:06 +0800 Subject: [PATCH 20/70] Update README.md --- spring-boot-modules/spring-boot-springdoc/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-springdoc/README.md b/spring-boot-modules/spring-boot-springdoc/README.md index 2447f30f6b..608e4afa2e 100644 --- a/spring-boot-modules/spring-boot-springdoc/README.md +++ b/spring-boot-modules/spring-boot-springdoc/README.md @@ -2,3 +2,4 @@ - [Documenting a Spring REST API Using OpenAPI 3.0](https://www.baeldung.com/spring-rest-openapi-documentation) - [Spring REST Docs vs OpenAPI](https://www.baeldung.com/spring-rest-docs-vs-openapi) +- [Hiding Endpoints From Swagger Documentation in Spring Boot](https://www.baeldung.com/spring-swagger-hiding-endpoints) From ec93dbe7f2d0f19a9710905e196403c46cf37563 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 10 Feb 2021 02:41:03 +0800 Subject: [PATCH 21/70] Update README.md --- guest/core-kotlin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guest/core-kotlin/README.md b/guest/core-kotlin/README.md index c211773f27..fad62ebea6 100644 --- a/guest/core-kotlin/README.md +++ b/guest/core-kotlin/README.md @@ -1,3 +1,3 @@ ### Relevant Articles: -- [Kotlin vs Java](https://www.baeldung.com/kotlin/kotlin-vs-java) +- [Kotlin vs Java](https://www.baeldung.com/kotlin/vs-java) From 0315847ad7e93d95590cba85158a153141df2434 Mon Sep 17 00:00:00 2001 From: Mateusz Szablak Date: Wed, 10 Feb 2021 00:40:55 +0100 Subject: [PATCH 22/70] Update PropertiesToHashMapConverter.java --- .../map/propertieshashmap/PropertiesToHashMapConverter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java index 2f333638a9..3472f998f5 100644 --- a/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java +++ b/core-java-modules/core-java-collections-maps-3/src/main/java/com/baeldung/map/propertieshashmap/PropertiesToHashMapConverter.java @@ -27,9 +27,9 @@ public class PropertiesToHashMapConverter { public static HashMap streamConvert(Properties prop) { return prop.entrySet().stream().collect( Collectors.toMap( - e -> String.valueOf(e.getKey()), - e -> String.valueOf(e.getValue()), - (prev, next) -> next, HashMap::new + e -> String.valueOf(e.getKey()), + e -> String.valueOf(e.getValue()), + (prev, next) -> next, HashMap::new )); } From 92b4049195720ee321e311dc7f0fca2ec40060f5 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 11 Feb 2021 01:07:33 +0800 Subject: [PATCH 23/70] Update README.md --- core-java-modules/core-java-lang-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-3/README.md b/core-java-modules/core-java-lang-3/README.md index 5279cc23b0..8ed945a56c 100644 --- a/core-java-modules/core-java-lang-3/README.md +++ b/core-java-modules/core-java-lang-3/README.md @@ -11,4 +11,5 @@ This module contains articles about core features in the Java language - [The transient Keyword in Java](https://www.baeldung.com/java-transient-keyword) - [How to Access an Iteration Counter in a For Each Loop](https://www.baeldung.com/java-foreach-counter) - [Comparing Doubles in Java](https://www.baeldung.com/java-comparing-doubles) +- [Guide to Implementing the compareTo Method](https://www.baeldung.com/java-compareto) - [[<-- Prev]](/core-java-modules/core-java-lang-2) From 4dda5a1a7c7d92fcc489767094e36002bb9374ca Mon Sep 17 00:00:00 2001 From: "Kent@lhind.hp.g5" Date: Wed, 10 Feb 2021 22:24:14 +0100 Subject: [PATCH 24/70] unchecked cast warning article --- .../baeldung/uncheckedcast/UncheckedCast.java | 26 +++++++++++++++++++ .../uncheckedcast/UncheckedCastUnitTest.java | 25 ++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/uncheckedcast/UncheckedCast.java create mode 100644 core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/uncheckedcast/UncheckedCastUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/uncheckedcast/UncheckedCast.java b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/uncheckedcast/UncheckedCast.java new file mode 100644 index 0000000000..fe79488d11 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/uncheckedcast/UncheckedCast.java @@ -0,0 +1,26 @@ +package com.baeldung.uncheckedcast; + +import java.time.LocalDate; +import java.time.Month; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class UncheckedCast { + public static Map getRawMap() { + Map rawMap = new HashMap(); + rawMap.put("date 1", LocalDate.of(2021, Month.FEBRUARY, 10)); + rawMap.put("date 2", LocalDate.of(1992, Month.AUGUST, 8)); + rawMap.put("date 3", LocalDate.of(1976, Month.NOVEMBER, 18)); + return rawMap; + } + + public static Map getRawMapWithMixedTypes() { + Map rawMap = new HashMap(); + rawMap.put("date 1", LocalDate.of(2021, Month.FEBRUARY, 10)); + rawMap.put("date 2", LocalDate.of(1992, Month.AUGUST, 8)); + rawMap.put("date 3", LocalDate.of(1976, Month.NOVEMBER, 18)); + rawMap.put("date 4", new Date()); + return rawMap; + } +} diff --git a/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/uncheckedcast/UncheckedCastUnitTest.java b/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/uncheckedcast/UncheckedCastUnitTest.java new file mode 100644 index 0000000000..b1bd46555e --- /dev/null +++ b/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/uncheckedcast/UncheckedCastUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.uncheckedcast; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDate; +import java.time.Month; +import java.util.Map; + +public class UncheckedCastUnitTest { + + @Test + public void givenRawMap_whenCastToTypedMap_shouldHaveCompilerWarning() { + Map castFromRawMap = (Map) UncheckedCast.getRawMap(); + Assert.assertEquals(3, castFromRawMap.size()); + Assert.assertEquals(castFromRawMap.get("date 2"), LocalDate.of(1992, Month.AUGUST, 8)); + } + + @Test(expected = ClassCastException.class) + public void givenMixTypedRawMap_whenCastToTypedMap_shouldThrowClassCastException() { + Map castFromRawMap = (Map) UncheckedCast.getRawMapWithMixedTypes(); + Assert.assertEquals(4, castFromRawMap.size()); + Assert.assertTrue(castFromRawMap.get("date 4").isAfter(castFromRawMap.get("date 3"))); + } +} From db46684ab9d8d462312637072a0fb2c23b3f6754 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 11 Feb 2021 18:20:25 +0800 Subject: [PATCH 25/70] Update README.md --- stripe/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stripe/README.md b/stripe/README.md index 9e41dcf945..36f0d6e3f3 100644 --- a/stripe/README.md +++ b/stripe/README.md @@ -5,4 +5,4 @@ This module contains articles about Stripe ### Relevant articles - [Introduction to the Stripe API for Java](https://www.baeldung.com/java-stripe-api) - +- [Viewing Contents of a JAR File](https://www.baeldung.com/java-view-jar-contents) From 676bc680f2def5434e9075ac97bd17bc4f134c44 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 11 Feb 2021 19:06:27 +0800 Subject: [PATCH 26/70] Update README.md --- .../spring-session/spring-session-jdbc/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/spring-security-modules/spring-session/spring-session-jdbc/README.md b/spring-security-modules/spring-session/spring-session-jdbc/README.md index a31ee044e8..6af3f53137 100644 --- a/spring-security-modules/spring-session/spring-session-jdbc/README.md +++ b/spring-security-modules/spring-session/spring-session-jdbc/README.md @@ -3,5 +3,3 @@ This module contains articles about Spring Session with JDBC. ### Relevant Articles: - -- [Spring Session with JDBC](https://www.baeldung.com/spring-session-jdbc) From 89eb93a46c195b775e8b817823f9238fc42f1e6e Mon Sep 17 00:00:00 2001 From: Hamid Reza Sharifi Date: Fri, 12 Feb 2021 14:20:52 +0330 Subject: [PATCH 27/70] Bael-4684-Prevent Cross-Site Scripting (XSS) in a Spring application-(new) (#10480) * #bael-4684: add main source code * #bael-4684: add test * #bael-4684: add required dependencies --- .../spring-5-security/pom.xml | 15 + .../java/com/baeldung/xss/Application.java | 14 + .../main/java/com/baeldung/xss/Person.java | 36 ++ .../com/baeldung/xss/PersonController.java | 31 + .../java/com/baeldung/xss/SecurityConf.java | 25 + .../main/java/com/baeldung/xss/XSSFilter.java | 44 ++ .../com/baeldung/xss/XSSRequestWrapper.java | 123 ++++ .../main/java/com/baeldung/xss/XSSUtils.java | 19 + .../src/main/resources/ESAPI.properties | 545 ++++++++++++++++++ .../xss/PersonControllerUnitTest.java | 64 ++ 10 files changed, 916 insertions(+) create mode 100644 spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Application.java create mode 100644 spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Person.java create mode 100644 spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/PersonController.java create mode 100644 spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/SecurityConf.java create mode 100644 spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSFilter.java create mode 100644 spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSRequestWrapper.java create mode 100644 spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSUtils.java create mode 100644 spring-security-modules/spring-5-security/src/main/resources/ESAPI.properties create mode 100644 spring-security-modules/spring-5-security/src/test/java/com/baeldung/xss/PersonControllerUnitTest.java diff --git a/spring-security-modules/spring-5-security/pom.xml b/spring-security-modules/spring-5-security/pom.xml index 09de91491c..f50b5ff7a9 100644 --- a/spring-security-modules/spring-5-security/pom.xml +++ b/spring-security-modules/spring-5-security/pom.xml @@ -46,6 +46,21 @@ spring-security-test test + + org.owasp.esapi + esapi + 2.2.2.0 + + + org.jsoup + jsoup + 1.13.1 + + + commons-io + commons-io + 2.8.0 + diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Application.java b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Application.java new file mode 100644 index 0000000000..b463a7adc3 --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.xss; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@SpringBootApplication +@EnableWebSecurity +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Person.java b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Person.java new file mode 100644 index 0000000000..1e7c02bae8 --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/Person.java @@ -0,0 +1,36 @@ +package com.baeldung.xss; + +public class Person { + private String firstName; + private String lastName; + private int age; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "Person {" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", age=" + age + '}'; + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/PersonController.java b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/PersonController.java new file mode 100644 index 0000000000..8486e04e48 --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/PersonController.java @@ -0,0 +1,31 @@ +package com.baeldung.xss; + +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestBody; + +import java.util.Map; + +@RestController +@RequestMapping("/personService") +public class PersonController { + + @PostMapping(value = "/person") + private ResponseEntity savePerson(@RequestHeader Map headers, + @RequestParam String param, @RequestBody Person body) { + ObjectNode response = JsonNodeFactory.instance.objectNode(); + headers.forEach((key, value) -> response.put(key, value)); + response.put("firstName", body.getFirstName()); + response.put("lastName", body.getLastName()); + response.put("age", body.getAge()); + response.put("param", param); + return new ResponseEntity(response.toString(), HttpStatus.OK); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/SecurityConf.java b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/SecurityConf.java new file mode 100644 index 0000000000..25d8026e4a --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/SecurityConf.java @@ -0,0 +1,25 @@ +package com.baeldung.xss; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConf extends WebSecurityConfigurerAdapter { + + @Override + public void configure(WebSecurity web) { + // Ignoring here is only for this example. Normally people would apply their own authentication/authorization policies + web.ignoring().antMatchers("/**"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .headers() + .xssProtection() + .and() + .contentSecurityPolicy("script-src 'self'"); + } +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSFilter.java b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSFilter.java new file mode 100644 index 0000000000..431ed4d120 --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSFilter.java @@ -0,0 +1,44 @@ +package com.baeldung.xss; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import javax.servlet.Filter; +import javax.servlet.FilterConfig; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.ServletException; +import javax.servlet.FilterChain; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +@Component +@Order(Ordered.HIGHEST_PRECEDENCE) +public class XSSFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) { + } + + @Override + public void destroy() { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + XSSRequestWrapper wrappedRequest = new XSSRequestWrapper((HttpServletRequest) request); + + String body = IOUtils.toString(wrappedRequest.getReader()); + if (!StringUtils.isBlank(body)) { + body = XSSUtils.stripXSS(body); + wrappedRequest.resetInputStream(body.getBytes()); + } + + chain.doFilter(wrappedRequest, response); + } + +} \ No newline at end of file diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSRequestWrapper.java b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSRequestWrapper.java new file mode 100644 index 0000000000..8fe4e20b5c --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSRequestWrapper.java @@ -0,0 +1,123 @@ +package com.baeldung.xss; + +import org.apache.commons.codec.Charsets; +import org.apache.commons.io.IOUtils; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +import static com.baeldung.xss.XSSUtils.stripXSS; + + +public class XSSRequestWrapper extends HttpServletRequestWrapper { + + private byte[] rawData; + private HttpServletRequest request; + private ResettableServletInputStream servletStream; + + public XSSRequestWrapper(HttpServletRequest request) { + super(request); + this.request = request; + this.servletStream = new ResettableServletInputStream(); + } + + public void resetInputStream(byte[] newRawData) { + rawData = newRawData; + servletStream.stream = new ByteArrayInputStream(newRawData); + } + + @Override + public ServletInputStream getInputStream() throws IOException { + if (rawData == null) { + rawData = IOUtils.toByteArray(this.request.getReader(), Charsets.UTF_8); + servletStream.stream = new ByteArrayInputStream(rawData); + } + return servletStream; + } + + @Override + public BufferedReader getReader() throws IOException { + if (rawData == null) { + rawData = IOUtils.toByteArray(this.request.getReader(), Charsets.UTF_8); + servletStream.stream = new ByteArrayInputStream(rawData); + } + return new BufferedReader(new InputStreamReader(servletStream)); + } + + private class ResettableServletInputStream extends ServletInputStream { + + private InputStream stream; + + @Override + public int read() throws IOException { + return stream.read(); + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + } + + @Override + public String[] getParameterValues(String parameter) { + String[] values = super.getParameterValues(parameter); + if (values == null) { + return null; + } + int count = values.length; + String[] encodedValues = new String[count]; + for (int i = 0; i < count; i++) { + encodedValues[i] = stripXSS(values[i]); + } + return encodedValues; + } + + @Override + public String getParameter(String parameter) { + String value = super.getParameter(parameter); + return stripXSS(value); + } + + @Override + public String getHeader(String name) { + String value = super.getHeader(name); + return stripXSS(value); + } + + @Override + public Enumeration getHeaders(String name) { + List result = new ArrayList<>(); + Enumeration headers = super.getHeaders(name); + while (headers.hasMoreElements()) { + String header = headers.nextElement(); + String[] tokens = header.split(","); + for (String token : tokens) { + result.add(stripXSS(token)); + } + } + return Collections.enumeration(result); + } + +} diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSUtils.java b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSUtils.java new file mode 100644 index 0000000000..51bcba8115 --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/java/com/baeldung/xss/XSSUtils.java @@ -0,0 +1,19 @@ +package com.baeldung.xss; + +import org.jsoup.Jsoup; +import org.jsoup.safety.Whitelist; +import org.owasp.esapi.ESAPI; + +public class XSSUtils { + + public static String stripXSS(String value) { + if (value == null) { + return null; + } + value = ESAPI.encoder() + .canonicalize(value) + .replaceAll("\0", ""); + return Jsoup.clean(value, Whitelist.none()); + } + +} diff --git a/spring-security-modules/spring-5-security/src/main/resources/ESAPI.properties b/spring-security-modules/spring-5-security/src/main/resources/ESAPI.properties new file mode 100644 index 0000000000..a2746a4dbc --- /dev/null +++ b/spring-security-modules/spring-5-security/src/main/resources/ESAPI.properties @@ -0,0 +1,545 @@ +# +# OWASP Enterprise Security API (ESAPI) Properties file -- PRODUCTION Version +# +# This file is part of the Open Web Application Security Project (OWASP) +# Enterprise Security API (ESAPI) project. For details, please see +# https://owasp.org/www-project-enterprise-security-api/ +# +# Copyright (c) 2008,2009 - The OWASP Foundation +# +# DISCUSS: This may cause a major backwards compatibility issue, etc. but +# from a name space perspective, we probably should have prefaced +# all the property names with ESAPI or at least OWASP. Otherwise +# there could be problems is someone loads this properties file into +# the System properties. We could also put this file into the +# esapi.jar file (perhaps as a ResourceBundle) and then allow an external +# ESAPI properties be defined that would overwrite these defaults. +# That keeps the application's properties relatively simple as usually +# they will only want to override a few properties. If looks like we +# already support multiple override levels of this in the +# DefaultSecurityConfiguration class, but I'm suggesting placing the +# defaults in the esapi.jar itself. That way, if the jar is signed, +# we could detect if those properties had been tampered with. (The +# code to check the jar signatures is pretty simple... maybe 70-90 LOC, +# but off course there is an execution penalty (similar to the way +# that the separate sunjce.jar used to be when a class from it was +# first loaded). Thoughts? +############################################################################### +# +# WARNING: Operating system protection should be used to lock down the .esapi +# resources directory and all the files inside and all the directories all the +# way up to the root directory of the file system. Note that if you are using +# file-based implementations, that some files may need to be read-write as they +# get updated dynamically. +# +#=========================================================================== +# ESAPI Configuration +# +# If true, then print all the ESAPI properties set here when they are loaded. +# If false, they are not printed. Useful to reduce output when running JUnit tests. +# If you need to troubleshoot a properties related problem, turning this on may help. +# This is 'false' in the src/test/resources/.esapi version. It is 'true' by +# default for reasons of backward compatibility with earlier ESAPI versions. +ESAPI.printProperties=true + +# ESAPI is designed to be easily extensible. You can use the reference implementation +# or implement your own providers to take advantage of your enterprise's security +# infrastructure. The functions in ESAPI are referenced using the ESAPI locator, like: +# +# String ciphertext = +# ESAPI.encryptor().encrypt("Secret message"); // Deprecated in 2.0 +# CipherText cipherText = +# ESAPI.encryptor().encrypt(new PlainText("Secret message")); // Preferred +# +# Below you can specify the classname for the provider that you wish to use in your +# application. The only requirement is that it implement the appropriate ESAPI interface. +# This allows you to switch security implementations in the future without rewriting the +# entire application. +# +# ExperimentalAccessController requires ESAPI-AccessControlPolicy.xml in .esapi directory +ESAPI.AccessControl=org.owasp.esapi.reference.DefaultAccessController +# FileBasedAuthenticator requires users.txt file in .esapi directory +ESAPI.Authenticator=org.owasp.esapi.reference.FileBasedAuthenticator +ESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoder +ESAPI.Encryptor=org.owasp.esapi.reference.crypto.JavaEncryptor + +ESAPI.Executor=org.owasp.esapi.reference.DefaultExecutor +ESAPI.HTTPUtilities=org.owasp.esapi.reference.DefaultHTTPUtilities +ESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetector +# Log4JFactory Requires log4j.xml or log4j.properties in classpath - http://www.laliluna.de/log4j-tutorial.html +# Note that this is now considered deprecated! +ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory +#ESAPI.Logger=org.owasp.esapi.logging.log4j.Log4JLogFactory +#ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory +# To use the new SLF4J logger in ESAPI (see GitHub issue #129), set +# ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory +# and do whatever other normal SLF4J configuration that you normally would do for your application. +ESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizer +ESAPI.Validator=org.owasp.esapi.reference.DefaultValidator + +#=========================================================================== +# ESAPI Authenticator +# +Authenticator.AllowedLoginAttempts=3 +Authenticator.MaxOldPasswordHashes=13 +Authenticator.UsernameParameterName=username +Authenticator.PasswordParameterName=password +# RememberTokenDuration (in days) +Authenticator.RememberTokenDuration=14 +# Session Timeouts (in minutes) +Authenticator.IdleTimeoutDuration=20 +Authenticator.AbsoluteTimeoutDuration=120 + +#=========================================================================== +# ESAPI Encoder +# +# ESAPI canonicalizes input before validation to prevent bypassing filters with encoded attacks. +# Failure to canonicalize input is a very common mistake when implementing validation schemes. +# Canonicalization is automatic when using the ESAPI Validator, but you can also use the +# following code to canonicalize data. +# +# ESAPI.Encoder().canonicalize( "%22hello world"" ); +# +# Multiple encoding is when a single encoding format is applied multiple times. Allowing +# multiple encoding is strongly discouraged. +Encoder.AllowMultipleEncoding=false + +# Mixed encoding is when multiple different encoding formats are applied, or when +# multiple formats are nested. Allowing multiple encoding is strongly discouraged. +Encoder.AllowMixedEncoding=false + +# The default list of codecs to apply when canonicalizing untrusted data. The list should include the codecs +# for all downstream interpreters or decoders. For example, if the data is likely to end up in a URL, HTML, or +# inside JavaScript, then the list of codecs below is appropriate. The order of the list is not terribly important. +Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec + + +#=========================================================================== +# ESAPI Encryption +# +# The ESAPI Encryptor provides basic cryptographic functions with a simplified API. +# To get started, generate a new key using java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor +# There is not currently any support for key rotation, so be careful when changing your key and salt as it +# will invalidate all signed, encrypted, and hashed data. +# +# WARNING: Not all combinations of algorithms and key lengths are supported. +# If you choose to use a key length greater than 128, you MUST download the +# unlimited strength policy files and install in the lib directory of your JRE/JDK. +# See http://java.sun.com/javase/downloads/index.jsp for more information. +# +# ***** IMPORTANT: Do NOT forget to replace these with your own values! ***** +# To calculate these values, you can run: +# java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor +# +#Encryptor.MasterKey= +#Encryptor.MasterSalt= + +# Provides the default JCE provider that ESAPI will "prefer" for its symmetric +# encryption and hashing. (That is it will look to this provider first, but it +# will defer to other providers if the requested algorithm is not implemented +# by this provider.) If left unset, ESAPI will just use your Java VM's current +# preferred JCE provider, which is generally set in the file +# "$JAVA_HOME/jre/lib/security/java.security". +# +# The main intent of this is to allow ESAPI symmetric encryption to be +# used with a FIPS 140-2 compliant crypto-module. For details, see the section +# "Using ESAPI Symmetric Encryption with FIPS 140-2 Cryptographic Modules" in +# the ESAPI 2.0 Symmetric Encryption User Guide, at: +# http://owasp-esapi-java.googlecode.com/svn/trunk/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html +# However, this property also allows you to easily use an alternate JCE provider +# such as "Bouncy Castle" without having to make changes to "java.security". +# See Javadoc for SecurityProviderLoader for further details. If you wish to use +# a provider that is not known to SecurityProviderLoader, you may specify the +# fully-qualified class name of the JCE provider class that implements +# java.security.Provider. If the name contains a '.', this is interpreted as +# a fully-qualified class name that implements java.security.Provider. +# +# NOTE: Setting this property has the side-effect of changing it in your application +# as well, so if you are using JCE in your application directly rather than +# through ESAPI (you wouldn't do that, would you? ;-), it will change the +# preferred JCE provider there as well. +# +# Default: Keeps the JCE provider set to whatever JVM sets it to. +Encryptor.PreferredJCEProvider= + +# AES is the most widely used and strongest encryption algorithm. This +# should agree with your Encryptor.CipherTransformation property. +# Warning: This property does not control the default reference implementation for +# ESAPI 2.0 using JavaEncryptor. Also, this property will be dropped +# in the future. +# @deprecated +Encryptor.EncryptionAlgorithm=AES +# For ESAPI Java 2.0 - New encrypt / decrypt methods use this. +Encryptor.CipherTransformation=AES/CBC/PKCS5Padding + +# Applies to ESAPI 2.0 and later only! +# Comma-separated list of cipher modes that provide *BOTH* +# confidentiality *AND* message authenticity. (NIST refers to such cipher +# modes as "combined modes" so that's what we shall call them.) If any of these +# cipher modes are used then no MAC is calculated and stored +# in the CipherText upon encryption. Likewise, if one of these +# cipher modes is used with decryption, no attempt will be made +# to validate the MAC contained in the CipherText object regardless +# of whether it contains one or not. Since the expectation is that +# these cipher modes support support message authenticity already, +# injecting a MAC in the CipherText object would be at best redundant. +# +# Note that as of JDK 1.5, the SunJCE provider does not support *any* +# of these cipher modes. Of these listed, only GCM and CCM are currently +# NIST approved. YMMV for other JCE providers. E.g., Bouncy Castle supports +# GCM and CCM with "NoPadding" mode, but not with "PKCS5Padding" or other +# padding modes. +Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC + +# Applies to ESAPI 2.0 and later only! +# Additional cipher modes allowed for ESAPI 2.0 encryption. These +# cipher modes are in _addition_ to those specified by the property +# 'Encryptor.cipher_modes.combined_modes'. +# Note: We will add support for streaming modes like CFB & OFB once +# we add support for 'specified' to the property 'Encryptor.ChooseIVMethod' +# (probably in ESAPI 2.1). +# DISCUSS: Better name? +Encryptor.cipher_modes.additional_allowed=CBC + +# Default key size to use for cipher specified by Encryptor.EncryptionAlgorithm. +# Note that this MUST be a valid key size for the algorithm being used +# (as specified by Encryptor.EncryptionAlgorithm). So for example, if AES is used, +# it must be 128, 192, or 256. If DESede is chosen, then it must be either 112 or 168. +# +# Note that 128-bits is almost always sufficient and for AES it appears to be more +# somewhat more resistant to related key attacks than is 256-bit AES.) +# +# Defaults to 128-bits if left blank. +# +# NOTE: If you use a key size > 128-bits, then you MUST have the JCE Unlimited +# Strength Jurisdiction Policy files installed!!! +# +Encryptor.EncryptionKeyLength=128 + +# This is the _minimum_ key size (in bits) that we allow with ANY symmetric +# cipher for doing encryption. (There is no minimum for decryption.) +# +# Generally, if you only use one algorithm, this should be set the same as +# the Encryptor.EncryptionKeyLength property. +Encryptor.MinEncryptionKeyLength=128 + +# Because 2.x uses CBC mode by default, it requires an initialization vector (IV). +# (All cipher modes except ECB require an IV.) There are two choices: we can either +# use a fixed IV known to both parties or allow ESAPI to choose a random IV. While +# the IV does not need to be hidden from adversaries, it is important that the +# adversary not be allowed to choose it. Also, random IVs are generally much more +# secure than fixed IVs. (In fact, it is essential that feed-back cipher modes +# such as CFB and OFB use a different IV for each encryption with a given key so +# in such cases, random IVs are much preferred. By default, ESAPI 2.0 uses random +# IVs. If you wish to use 'fixed' IVs, set 'Encryptor.ChooseIVMethod=fixed' and +# uncomment the Encryptor.fixedIV. +# +# Valid values: random|fixed|specified 'specified' not yet implemented; planned for 2.3 +# 'fixed' is deprecated as of 2.2 +# and will be removed in 2.3. +Encryptor.ChooseIVMethod=random + + +# If you choose to use a fixed IV, then you must place a fixed IV here that +# is known to all others who are sharing your secret key. The format should +# be a hex string that is the same length as the cipher block size for the +# cipher algorithm that you are using. The following is an *example* for AES +# from an AES test vector for AES-128/CBC as described in: +# NIST Special Publication 800-38A (2001 Edition) +# "Recommendation for Block Cipher Modes of Operation". +# (Note that the block size for AES is 16 bytes == 128 bits.) +# +# @Deprecated -- fixed IVs are deprecated as of the 2.2 release and support +# will be removed in the next release (tentatively, 2.3). +# If you MUST use this, at least replace this IV with one +# that your legacy application was using. +Encryptor.fixedIV=0x000102030405060708090a0b0c0d0e0f + +# Whether or not CipherText should use a message authentication code (MAC) with it. +# This prevents an adversary from altering the IV as well as allowing a more +# fool-proof way of determining the decryption failed because of an incorrect +# key being supplied. This refers to the "separate" MAC calculated and stored +# in CipherText, not part of any MAC that is calculated as a result of a +# "combined mode" cipher mode. +# +# If you are using ESAPI with a FIPS 140-2 cryptographic module, you *must* also +# set this property to false. That is because ESAPI takes the master key and +# derives 2 keys from it--a key for the MAC and a key for encryption--and +# because ESAPI is not itself FIPS 140-2 verified such intermediary aterations +# to keys from FIPS approved sources would have the effect of making your FIPS +# approved key generation and thus your FIPS approved JCE provider unapproved! +# More details in +# documentation/esapi4java-core-2.0-readme-crypto-changes.html +# documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html +# You have been warned. +Encryptor.CipherText.useMAC=true + +# Whether or not the PlainText object may be overwritten and then marked +# eligible for garbage collection. If not set, this is still treated as 'true'. +Encryptor.PlainText.overwrite=true + +# Do not use DES except in a legacy situations. 56-bit is way too small key size. +#Encryptor.EncryptionKeyLength=56 +#Encryptor.MinEncryptionKeyLength=56 +#Encryptor.EncryptionAlgorithm=DES + +# TripleDES is considered strong enough for most purposes. +# Note: There is also a 112-bit version of DESede. Using the 168-bit version +# requires downloading the special jurisdiction policy from Sun. +#Encryptor.EncryptionKeyLength=168 +#Encryptor.MinEncryptionKeyLength=112 +#Encryptor.EncryptionAlgorithm=DESede + +Encryptor.HashAlgorithm=SHA-512 +Encryptor.HashIterations=1024 +Encryptor.DigitalSignatureAlgorithm=SHA1withDSA +Encryptor.DigitalSignatureKeyLength=1024 +Encryptor.RandomAlgorithm=SHA1PRNG +Encryptor.CharacterEncoding=UTF-8 + +# This is the Pseudo Random Function (PRF) that ESAPI's Key Derivation Function +# (KDF) normally uses. Note this is *only* the PRF used for ESAPI's KDF and +# *not* what is used for ESAPI's MAC. (Currently, HmacSHA1 is always used for +# the MAC, mostly to keep the overall size at a minimum.) +# +# Currently supported choices for JDK 1.5 and 1.6 are: +# HmacSHA1 (160 bits), HmacSHA256 (256 bits), HmacSHA384 (384 bits), and +# HmacSHA512 (512 bits). +# Note that HmacMD5 is *not* supported for the PRF used by the KDF even though +# the JDKs support it. See the ESAPI 2.0 Symmetric Encryption User Guide +# further details. +Encryptor.KDF.PRF=HmacSHA256 +#=========================================================================== +# ESAPI HttpUtilties +# +# The HttpUtilities provide basic protections to HTTP requests and responses. Primarily these methods +# protect against malicious data from attackers, such as unprintable characters, escaped characters, +# and other simple attacks. The HttpUtilities also provides utility methods for dealing with cookies, +# headers, and CSRF tokens. +# +# Default file upload location (remember to escape backslashes with \\) +HttpUtilities.UploadDir=C:\\ESAPI\\testUpload +HttpUtilities.UploadTempDir=C:\\temp +# Force flags on cookies, if you use HttpUtilities to set cookies +HttpUtilities.ForceHttpOnlySession=false +HttpUtilities.ForceSecureSession=false +HttpUtilities.ForceHttpOnlyCookies=true +HttpUtilities.ForceSecureCookies=true +# Maximum size of HTTP header key--the validator regex may have additional values. +HttpUtilities.MaxHeaderNameSize=256 +# Maximum size of HTTP header value--the validator regex may have additional values. +HttpUtilities.MaxHeaderValueSize=4096 +# Maximum size of JSESSIONID for the application--the validator regex may have additional values. +HttpUtilities.HTTPJSESSIONIDLENGTH=50 +# Maximum length of a URL (see https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers) +HttpUtilities.URILENGTH=2000 +# Maximum length of a redirect +HttpUtilities.maxRedirectLength=512 +# Maximum length for an http scheme +HttpUtilities.HTTPSCHEMELENGTH=10 +# Maximum length for an http host +HttpUtilities.HTTPHOSTLENGTH=100 +# Maximum length for an http path +HttpUtilities.HTTPPATHLENGTH=150 +#Maximum length for a context path +HttpUtilities.contextPathLength=150 +#Maximum length for an httpServletPath +HttpUtilities.HTTPSERVLETPATHLENGTH=100 +#Maximum length for an http query parameter name +HttpUtilities.httpQueryParamNameLength=100 +#Maximum length for an http query parameter -- old default was 2000, but that's the max length for a URL... +HttpUtilities.httpQueryParamValueLength=500 +# File upload configuration +HttpUtilities.ApprovedUploadExtensions=.pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx,.rtf,.txt,.jpg,.png +HttpUtilities.MaxUploadFileBytes=500000000 +# Using UTF-8 throughout your stack is highly recommended. That includes your database driver, +# container, and any other technologies you may be using. Failure to do this may expose you +# to Unicode transcoding injection attacks. Use of UTF-8 does not hinder internationalization. +HttpUtilities.ResponseContentType=text/html; charset=UTF-8 +# This is the name of the cookie used to represent the HTTP session +# Typically this will be the default "JSESSIONID" +HttpUtilities.HttpSessionIdName=JSESSIONID +#Sets whether or not we will overwrite http status codes to 200. +HttpUtilities.OverwriteStatusCodes=true +#Sets the application's base character encoding. This is forked from the Java Encryptor property. +HttpUtilities.CharacterEncoding=UTF-8 + +#=========================================================================== +# ESAPI Executor +# CHECKME - This should be made OS independent. Don't use unsafe defaults. +# # Examples only -- do NOT blindly copy! +# For Windows: +# Executor.WorkingDirectory=C:\\Windows\\Temp +# Executor.ApprovedExecutables=C:\\Windows\\System32\\cmd.exe,C:\\Windows\\System32\\runas.exe +# For *nux, MacOS: +# Executor.WorkingDirectory=/tmp +# Executor.ApprovedExecutables=/bin/bash +Executor.WorkingDirectory= +Executor.ApprovedExecutables= + + +#=========================================================================== +# ESAPI Logging +# Set the application name if these logs are combined with other applications +Logger.ApplicationName=ExampleApplication +# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true +Logger.LogEncodingRequired=false +# Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments. +Logger.LogApplicationName=true +# Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments. +Logger.LogServerIP=true +# LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you +# want to place it in a specific directory. +Logger.LogFileName=ESAPI_logging_file +# MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000) +Logger.MaxLogFileSize=10000000 +# Determines whether ESAPI should log the user info. +Logger.UserInfo=true +# Determines whether ESAPI should log the session id and client IP. +Logger.ClientInfo=true + +#=========================================================================== +# ESAPI Intrusion Detection +# +# Each event has a base to which .count, .interval, and .action are added +# The IntrusionException will fire if we receive "count" events within "interval" seconds +# The IntrusionDetector is configurable to take the following actions: log, logout, and disable +# (multiple actions separated by commas are allowed e.g. event.test.actions=log,disable +# +# Custom Events +# Names must start with "event." as the base +# Use IntrusionDetector.addEvent( "test" ) in your code to trigger "event.test" here +# You can also disable intrusion detection completely by changing +# the following parameter to true +# +IntrusionDetector.Disable=false +# +IntrusionDetector.event.test.count=2 +IntrusionDetector.event.test.interval=10 +IntrusionDetector.event.test.actions=disable,log + +# Exception Events +# All EnterpriseSecurityExceptions are registered automatically +# Call IntrusionDetector.getInstance().addException(e) for Exceptions that do not extend EnterpriseSecurityException +# Use the fully qualified classname of the exception as the base + +# any intrusion is an attack +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.count=1 +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.interval=1 +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout + +# for test purposes +# CHECKME: Shouldn't there be something in the property name itself that designates +# that these are for testing??? +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.count=10 +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.interval=5 +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout + +# rapid validation errors indicate scans or attacks in progress +# org.owasp.esapi.errors.ValidationException.count=10 +# org.owasp.esapi.errors.ValidationException.interval=10 +# org.owasp.esapi.errors.ValidationException.actions=log,logout + +# sessions jumping between hosts indicates session hijacking +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.count=2 +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.interval=10 +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout + + +#=========================================================================== +# ESAPI Validation +# +# The ESAPI Validator works on regular expressions with defined names. You can define names +# either here, or you may define application specific patterns in a separate file defined below. +# This allows enterprises to specify both organizational standards as well as application specific +# validation rules. +# +# Use '\p{L}' (without the quotes) within the character class to match +# any Unicode LETTER. You can also use a range, like: \u00C0-\u017F +# You can also use any of the regex flags as documented at +# https://docs.oracle.com/javase/tutorial/essential/regex/pattern.html, e.g. (?u) +# +Validator.ConfigurationFile=validation.properties + +# Validators used by ESAPI +Validator.AccountName=^[a-zA-Z0-9]{3,20}$ +Validator.SystemCommand=^[a-zA-Z\\-\\/]{1,64}$ +Validator.RoleName=^[a-z]{1,20}$ + +#the word TEST below should be changed to your application +#name - only relative URL's are supported +Validator.Redirect=^\\/test.*$ + +# Global HTTP Validation Rules +# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=] +Validator.HTTPScheme=^(http|https)$ +Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$ +Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{1,32}$ +Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$ +# Note that headerName and Value length is also configured in the HTTPUtilities section +Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{1,256}$ +Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$ +Validator.HTTPServletPath=^[a-zA-Z0-9.\\-\\/_]*$ +Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$ +Validator.HTTPURL=^.*$ +Validator.HTTPJSESSIONID=^[A-Z0-9]{10,32}$ + + +# Contributed by Fraenku@gmx.ch +# Github Issue 126 https://github.com/ESAPI/esapi-java-legacy/issues/126 +Validator.HTTPParameterName=^[a-zA-Z0-9_\\-]{1,32}$ +Validator.HTTPParameterValue=^[\\p{L}\\p{N}.\\-/+=_ !$*?@]{0,1000}$ +Validator.HTTPContextPath=^/[a-zA-Z0-9.\\-_]*$ +Validator.HTTPQueryString=^([a-zA-Z0-9_\\-]{1,32}=[\\p{L}\\p{N}.\\-/+=_ !$*?@%]*&?)*$ +Validator.HTTPURI=^/([a-zA-Z0-9.\\-_]*/?)*$ + + +# Validation of file related input +Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ +Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ + +# Validation of dates. Controls whether or not 'lenient' dates are accepted. +# See DataFormat.setLenient(boolean flag) for further details. +Validator.AcceptLenientDates=false + +# ~~~~~ Important Note ~~~~~ +# This is a workaround to make sure that a commit to address GitHub issue #509 +# doesn't accidentally break someone's production code. So essentially what we +# are doing is to reverting back to the previous possibly buggy (by +# documentation intent at least), but, by now, expected legacy behavior. +# Prior to the code changes for issue #509, if invalid / malicious HTML input was +# observed, AntiSamy would simply attempt to sanitize (cleanse) it and it would +# only be logged. However, the code change made ESAPI comply with its +# documentation, which stated that a ValidationException should be thrown in +# such cases. Unfortunately, changing this behavior--especially when no one is +# 100% certain that the documentation was correct--could break existing code +# using ESAPI so after a lot of debate, issue #521 was created to restore the +# previous behavior, but still allow the documented behavior. (We did this +# because it wasn't really causing an security issues since AntiSamy would clean +# it up anyway and we value backward compatibility as long as it doesn't clearly +# present security vulnerabilities.) +# More defaults about this are written up under GitHub issue #521 and +# the pull request it references. Future major releases of ESAPI (e.g., ESAPI 3.x) +# will not support this previous behavior, but it will remain for ESAPI 2.x. +# Set this to 'throw' if you want the originally intended behavior of throwing +# that was fixed via issue #509. Set to 'clean' if you want want the HTML input +# sanitized instead. +# +# Possible values: +# clean -- Use the legacy behavior where unsafe HTML input is logged and the +# sanitized (i.e., clean) input as determined by AntiSamy and your +# AntiSamy rules is returned. This is the default behavior if this +# new property is not found. +# throw -- The new, presumably correct and originally intended behavior where +# a ValidationException is thrown when unsafe HTML input is +# encountered. +# +#Validator.HtmlValidationAction=clean +Validator.HtmlValidationAction=throw + +# With the fix for #310 to enable loading antisamy-esapi.xml from the classpath +# also an enhancement was made to be able to use a different filename for the configuration. +# You don't have to configure the filename here, but in that case the code will keep looking for antisamy-esapi.xml. +# This is the default behaviour of ESAPI. +# +#Validator.HtmlValidationConfigurationFile=antisamy-esapi.xml \ No newline at end of file diff --git a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/xss/PersonControllerUnitTest.java b/spring-security-modules/spring-5-security/src/test/java/com/baeldung/xss/PersonControllerUnitTest.java new file mode 100644 index 0000000000..4e278ebf16 --- /dev/null +++ b/spring-security-modules/spring-5-security/src/test/java/com/baeldung/xss/PersonControllerUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.xss; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.*; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; +import java.io.IOException; +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class PersonControllerUnitTest { + + @LocalServerPort + int randomServerPort; + + @Test + public void givenRequestIsSuspicious_whenRequestIsPost_thenResponseIsClean() + throws IOException { + // given + String createPersonUrl; + RestTemplate restTemplate; + HttpHeaders headers; + UriComponentsBuilder builder; + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode personJsonObject = JsonNodeFactory.instance.objectNode(); + createPersonUrl = "http://localhost:" + randomServerPort + "/personService/person"; + restTemplate = new RestTemplate(); + headers = new HttpHeaders(); + + // when + personJsonObject.put("id", 1); + personJsonObject.put("firstName", "baeldung "); + personJsonObject.put("lastName", "baeldung click me!"); + + builder = UriComponentsBuilder.fromHttpUrl(createPersonUrl) + .queryParam("param", ""); + headers.add("header_4", "

Your search for 'flowers '"); + HttpEntity request = new HttpEntity<>(personJsonObject.toString(), headers); + + ResponseEntity personResultAsJsonStr = restTemplate.exchange(builder.toUriString(), + HttpMethod.POST, request, String.class); + JsonNode root = objectMapper.readTree(personResultAsJsonStr.getBody()); + + // then + assertThat(root.get("firstName").textValue()).isEqualTo("baeldung "); + assertThat(root.get("lastName").textValue()).isEqualTo("baeldung click me!"); + assertThat(root.get("param").textValue()).isEmpty(); + assertThat(root.get("header_1").textValue()).isEmpty(); + assertThat(root.get("header_2").textValue()).isEmpty(); + assertThat(root.get("header_3").textValue()).isEmpty(); + assertThat(root.get("header_4").textValue()).isEqualTo("Your search for 'flowers '"); + } +} From dc6e305e1fa6c769dd2f6898ea014e162b6c2084 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Fri, 12 Feb 2021 20:08:12 -0300 Subject: [PATCH 28/70] fixed potential error using webClient without specifying url, and improved timeout test case --- .../web/client/WebClientIntegrationTest.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java index 39adf0b5c0..d7c31d627a 100644 --- a/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java +++ b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java @@ -11,8 +11,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.web.server.LocalServerPort; @@ -41,6 +39,7 @@ import com.baeldung.web.reactive.client.Foo; import com.baeldung.web.reactive.client.WebClientApplication; import io.netty.channel.ChannelOption; +import io.netty.handler.timeout.ReadTimeoutException; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import reactor.core.publisher.Mono; @@ -265,17 +264,17 @@ public class WebClientIntegrationTest { .addHandlerLast(new WriteTimeoutHandler(1000, TimeUnit.MILLISECONDS))); WebClient timeoutClient = WebClient.builder() + .baseUrl("http://localhost:" + port) .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); - BodyInserter, ReactiveHttpOutputMessage> inserterCompleteSuscriber = BodyInserters.fromPublisher(Subscriber::onComplete, String.class); - RequestHeadersSpec headersSpecInserterCompleteSuscriber = timeoutClient.post() + StepVerifier.create(timeoutClient.post() .uri("/resource") - .body(inserterCompleteSuscriber); - - StepVerifier.create(headersSpecInserterCompleteSuscriber.retrieve() + .body(Mono.never(), String.class) + .retrieve() .bodyToMono(String.class)) - .expectTimeout(Duration.ofMillis(2000)) + .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ReadTimeoutException.class.isAssignableFrom(ex.getCause() + .getClass())) .verify(); } From 19d64f6152a054603d1f03b1a9bf95273c1c18a5 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Fri, 12 Feb 2021 20:17:12 -0300 Subject: [PATCH 29/70] change just to stick to original variable declaration approach --- .../com/baeldung/web/client/WebClientIntegrationTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java index d7c31d627a..7e1fc86847 100644 --- a/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java +++ b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java @@ -268,10 +268,11 @@ public class WebClientIntegrationTest { .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); - StepVerifier.create(timeoutClient.post() + RequestHeadersSpec neverendingMonoBodyRequest = timeoutClient.post() .uri("/resource") - .body(Mono.never(), String.class) - .retrieve() + .body(Mono.never(), String.class); + + StepVerifier.create(neverendingMonoBodyRequest.retrieve() .bodyToMono(String.class)) .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ReadTimeoutException.class.isAssignableFrom(ex.getCause() .getClass())) From 60a19ec9f48b2c25cbfff229466fb469e06765ad Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Sat, 13 Feb 2021 11:38:55 +0000 Subject: [PATCH 30/70] BAEL-4672 added content for JMeter extract data to file tutorial --- jmeter/README.md | 11 +- .../baeldung/controller/TestController.java | 18 +++ .../java/com/baeldung/model/Response.java | 40 ++++++ .../main/resources/FileExtractionExample.jmx | 124 ++++++++++++++++++ .../com/baeldung/JmeterIntegrationTest.java | 36 +++++ 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 jmeter/src/main/java/com/baeldung/controller/TestController.java create mode 100644 jmeter/src/main/java/com/baeldung/model/Response.java create mode 100644 jmeter/src/main/resources/FileExtractionExample.jmx create mode 100644 jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java diff --git a/jmeter/README.md b/jmeter/README.md index 81300afe7c..84677ad618 100644 --- a/jmeter/README.md +++ b/jmeter/README.md @@ -7,7 +7,7 @@ It contains the code of a simple API for some CRUD operations built using Spring - Maven - JDK 8 -- MongoDB +- MongoDB (Note: for the Write Extracted Data to a File Using JMeter example MongoDB is not required) ### Running @@ -36,6 +36,14 @@ Or create a new one via a POST: $ curl -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Dassi", "lastName" : "Orleando", "phoneNumber": "+237 545454545", "email": "mymail@yahoo.fr" }' localhost:8080/students ``` +### Available Test API + +You can view the test response using curl: + +```bash +$ curl localhost:8080/api/test +``` + Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080) Enjoy it :) @@ -44,3 +52,4 @@ Enjoy it :) - [Intro to Performance Testing using JMeter](https://www.baeldung.com/jmeter) - [Configure Jenkins to Run and Show JMeter Tests](https://www.baeldung.com/jenkins-and-jmeter) +- [Write Extracted Data to a File Using JMeter](https://www.baeldung.com/jmeter-file-extraction) diff --git a/jmeter/src/main/java/com/baeldung/controller/TestController.java b/jmeter/src/main/java/com/baeldung/controller/TestController.java new file mode 100644 index 0000000000..6e286265d3 --- /dev/null +++ b/jmeter/src/main/java/com/baeldung/controller/TestController.java @@ -0,0 +1,18 @@ +package com.baeldung.controller; + +import com.baeldung.model.Response; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +import static java.lang.String.format; + +@RestController +public class TestController { + + @GetMapping("/api/test") + public Response test() { + return new Response(format("Test message... %s.", UUID.randomUUID())); + } +} diff --git a/jmeter/src/main/java/com/baeldung/model/Response.java b/jmeter/src/main/java/com/baeldung/model/Response.java new file mode 100644 index 0000000000..547e5b536e --- /dev/null +++ b/jmeter/src/main/java/com/baeldung/model/Response.java @@ -0,0 +1,40 @@ +package com.baeldung.model; + +import java.time.Instant; +import java.util.UUID; + +public class Response { + private Instant timestamp; + private UUID uuid; + private String message; + + public Response(String message) { + this.timestamp = Instant.now(); + this.uuid = UUID.randomUUID(); + this.message = message; + } + + public Instant getTimestamp() { + return timestamp; + } + + public void setTimestamp(Instant timestamp) { + this.timestamp = timestamp; + } + + public UUID getUuid() { + return uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/jmeter/src/main/resources/FileExtractionExample.jmx b/jmeter/src/main/resources/FileExtractionExample.jmx new file mode 100644 index 0000000000..e2047d0528 --- /dev/null +++ b/jmeter/src/main/resources/FileExtractionExample.jmx @@ -0,0 +1,124 @@ + + + + + To run this test plan you must also be running the Spring application "JmeterApplication" That can be found in this directory + false + true + false + + + + + + + + continue + + false + 1 + + 1 + 1 + false + + + true + + + + + + + localhost + 8080 + http + + /api/test + GET + true + false + true + false + + + + + + + message + $.message + 1 + true + NOT_FOUND + + + + + + false + FileWriter fWriter = new FileWriter("/Users/liamgarvie/Documents/result.txt", true); +BufferedWriter buff = new BufferedWriter(fWriter); + +buff.write("Response Code : " + ctx.getPreviousResult().getResponseCode()); +buff.write(System.getProperty("line.separator")); +buff.write("Response Headers : " + ctx.getPreviousResult().getResponseHeaders()); +buff.write(System.getProperty("line.separator")); +buff.write("Response Body : " + new String(ctx.getPreviousResult().getResponseData())); + +buff.write("More complex extraction : " + vars.get("message")); + +buff.close(); +fWriter.close(); + + + + response + false + false + false + false + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + + + diff --git a/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java b/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java new file mode 100644 index 0000000000..5ccbeb875b --- /dev/null +++ b/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java @@ -0,0 +1,36 @@ +package com.baeldung; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; +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.status; + +@SpringBootTest +class JmeterIntegrationTest { + + MockMvc mvc; + + public JmeterIntegrationTest(WebApplicationContext wac) { + this.mvc = MockMvcBuilders.webAppContextSetup(wac).build(); + } + + @Test + void whenCallingTestController_thenWeShouldRecieveRandomizedResponse() throws Exception { + MockHttpServletResponse response = mvc.perform(get("/api/test")) + .andDo(print()) + .andExpect(status().isOk()) + .andReturn() + .getResponse(); + + assertThat(response.getContentAsString()) + .contains("Test message..."); + } + +} From 354018732d8241fd8598932fbbab9a79265f9ecf Mon Sep 17 00:00:00 2001 From: Jordan Simpson Date: Sat, 13 Feb 2021 14:29:50 -0600 Subject: [PATCH 31/70] Added a new module (spring-core-5) for the code examples of BAEL-4764. (#10484) --- pom.xml | 2 + spring-core-3/README.md | 2 +- spring-core-4/README.md | 2 +- spring-core-5/README.md | 7 +++ spring-core-5/pom.xml | 46 ++++++++++++++++ .../component/inscope/AmbiguousBean.java | 4 ++ .../component/inscope/BeanExample.java | 4 ++ .../baeldung/component/inscope/BeanImplA.java | 4 ++ .../baeldung/component/inscope/BeanImplB.java | 4 ++ .../inscope/ComponentApplication.java | 42 +++++++++++++++ .../component/inscope/ComponentExample.java | 7 +++ .../component/inscope/ControllerExample.java | 7 +++ .../component/inscope/CustomComponent.java | 14 +++++ .../inscope/CustomComponentExample.java | 5 ++ .../component/inscope/RepositoryExample.java | 7 +++ .../component/inscope/ServiceExample.java | 7 +++ .../outsidescope/OutsideScopeBeanExample.java | 4 ++ .../outsidescope/OutsideScopeExample.java | 7 +++ .../scannedscope/ScannedScopeExample.java | 7 +++ .../src/main/resources/application.yml | 1 + .../component/inscope/ComponentUnitTest.java | 54 +++++++++++++++++++ .../src/test/resources/application.yml | 1 + 22 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 spring-core-5/README.md create mode 100644 spring-core-5/pom.xml create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/BeanExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplA.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplB.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentApplication.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/ControllerExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponent.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/RepositoryExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/inscope/ServiceExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java create mode 100644 spring-core-5/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java create mode 100644 spring-core-5/src/main/resources/application.yml create mode 100644 spring-core-5/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java create mode 100644 spring-core-5/src/test/resources/application.yml diff --git a/pom.xml b/pom.xml index 70efb02f4d..ccdc91ffe0 100644 --- a/pom.xml +++ b/pom.xml @@ -631,6 +631,7 @@ spring-core-2 spring-core-3 spring-core-4 + spring-core-5 spring-cucumber spring-data-rest @@ -1082,6 +1083,7 @@ spring-core-2 spring-core-3 spring-core-4 + spring-core-5 spring-cucumber spring-data-rest diff --git a/spring-core-3/README.md b/spring-core-3/README.md index b6257cb9a4..7232ad71a1 100644 --- a/spring-core-3/README.md +++ b/spring-core-3/README.md @@ -11,4 +11,4 @@ This module contains articles about core Spring functionality - [Difference Between BeanFactory and ApplicationContext](https://www.baeldung.com/spring-beanfactory-vs-applicationcontext) - [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor) - [Custom Scope in Spring](http://www.baeldung.com/spring-custom-scope) -- More articles: [[<-- prev]](/spring-core-2) +- More articles: [[<-- prev]](/spring-core-2) [[next -->]](/spring-core-4) diff --git a/spring-core-4/README.md b/spring-core-4/README.md index 03a6747c1d..3b2c3d4764 100644 --- a/spring-core-4/README.md +++ b/spring-core-4/README.md @@ -11,4 +11,4 @@ This module contains articles about core Spring functionality - [Using @Autowired in Abstract Classes](https://www.baeldung.com/spring-autowired-abstract-class) - [Constructor Injection in Spring with Lombok](https://www.baeldung.com/spring-injection-lombok) - [The Spring ApplicationContext](https://www.baeldung.com/spring-application-context) -- More articles: [[<-- prev]](/spring-core-3) +- More articles: [[<-- prev]](/spring-core-3) [[next -->]](/spring-core-5) diff --git a/spring-core-5/README.md b/spring-core-5/README.md new file mode 100644 index 0000000000..81669e46a7 --- /dev/null +++ b/spring-core-5/README.md @@ -0,0 +1,7 @@ +## Spring Core + +This module contains articles about core Spring functionality + +## Relevant Articles: + +- More articles: [[<-- prev]](/spring-core-4) \ No newline at end of file diff --git a/spring-core-5/pom.xml b/spring-core-5/pom.xml new file mode 100644 index 0000000000..743002c137 --- /dev/null +++ b/spring-core-5/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + spring-core-5 + spring-core-5 + + + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 + + + + + org.springframework.boot + spring-boot-starter + ${spring-boot-starter.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot-starter.version} + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.version} + + + + + + 5.3.3 + 2.4.2 + 2.22.1 + + + diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java new file mode 100644 index 0000000000..70e1f0a79a --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/AmbiguousBean.java @@ -0,0 +1,4 @@ +package com.baeldung.component.inscope; + +public interface AmbiguousBean { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanExample.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanExample.java new file mode 100644 index 0000000000..d1b4cd34f1 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanExample.java @@ -0,0 +1,4 @@ +package com.baeldung.component.inscope; + +public class BeanExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplA.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplA.java new file mode 100644 index 0000000000..08e1661499 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplA.java @@ -0,0 +1,4 @@ +package com.baeldung.component.inscope; + +public class BeanImplA implements AmbiguousBean { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplB.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplB.java new file mode 100644 index 0000000000..8a45581532 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/BeanImplB.java @@ -0,0 +1,4 @@ +package com.baeldung.component.inscope; + +public class BeanImplB implements AmbiguousBean { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentApplication.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentApplication.java new file mode 100644 index 0000000000..604e7d6632 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentApplication.java @@ -0,0 +1,42 @@ +package com.baeldung.component.inscope; + +import com.baeldung.component.outsidescope.OutsideScopeBeanExample; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@SpringBootApplication +@ComponentScan({"com.baeldung.component.inscope", "com.baeldung.component.scannedscope"}) +@Configuration +public class ComponentApplication { + + @Value( "${ambiguous-bean}" ) + public String ambiguousBean; + + public static void main(String[] args) { + SpringApplication.run( ComponentApplication.class, args ); + } + + @Bean + public BeanExample beanExample() { + return new BeanExample(); + } + + @Bean + public OutsideScopeBeanExample outsideScopeBeanExample() { + return new OutsideScopeBeanExample(); + } + + @Bean + public AmbiguousBean ambiguousBean() { + if (ambiguousBean.equals("A")) { + return new BeanImplA(); + } + else { + return new BeanImplB(); + } + } +} \ No newline at end of file diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentExample.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentExample.java new file mode 100644 index 0000000000..66d3e20d34 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/ComponentExample.java @@ -0,0 +1,7 @@ +package com.baeldung.component.inscope; + +import org.springframework.stereotype.Component; + +@Component +public class ComponentExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ControllerExample.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/ControllerExample.java new file mode 100644 index 0000000000..773af2a113 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/ControllerExample.java @@ -0,0 +1,7 @@ +package com.baeldung.component.inscope; + +import org.springframework.stereotype.Controller; + +@Controller +public class ControllerExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponent.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponent.java new file mode 100644 index 0000000000..795a1b23fa --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponent.java @@ -0,0 +1,14 @@ +package com.baeldung.component.inscope; + +import org.springframework.stereotype.Component; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Component +public @interface CustomComponent { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java new file mode 100644 index 0000000000..8009f8ec20 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/CustomComponentExample.java @@ -0,0 +1,5 @@ +package com.baeldung.component.inscope; + +@CustomComponent +public class CustomComponentExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/RepositoryExample.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/RepositoryExample.java new file mode 100644 index 0000000000..9297992904 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/RepositoryExample.java @@ -0,0 +1,7 @@ +package com.baeldung.component.inscope; + +import org.springframework.stereotype.Repository; + +@Repository +public class RepositoryExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/inscope/ServiceExample.java b/spring-core-5/src/main/java/com/baeldung/component/inscope/ServiceExample.java new file mode 100644 index 0000000000..e2db60504a --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/inscope/ServiceExample.java @@ -0,0 +1,7 @@ +package com.baeldung.component.inscope; + +import org.springframework.stereotype.Service; + +@Service +public class ServiceExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java b/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java new file mode 100644 index 0000000000..079c012862 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeBeanExample.java @@ -0,0 +1,4 @@ +package com.baeldung.component.outsidescope; + +public class OutsideScopeBeanExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java b/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java new file mode 100644 index 0000000000..5c7fff959d --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/outsidescope/OutsideScopeExample.java @@ -0,0 +1,7 @@ +package com.baeldung.component.outsidescope; + +import org.springframework.stereotype.Component; + +@Component +public class OutsideScopeExample { +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java b/spring-core-5/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java new file mode 100644 index 0000000000..59873634d6 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/scannedscope/ScannedScopeExample.java @@ -0,0 +1,7 @@ +package com.baeldung.component.scannedscope; + +import org.springframework.stereotype.Component; + +@Component +public class ScannedScopeExample { +} diff --git a/spring-core-5/src/main/resources/application.yml b/spring-core-5/src/main/resources/application.yml new file mode 100644 index 0000000000..5c09fdb8b0 --- /dev/null +++ b/spring-core-5/src/main/resources/application.yml @@ -0,0 +1 @@ +ambiguous-bean: 'A' \ No newline at end of file diff --git a/spring-core-5/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java b/spring-core-5/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java new file mode 100644 index 0000000000..09ce604d40 --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/component/inscope/ComponentUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.component.inscope; + +import com.baeldung.component.outsidescope.OutsideScopeBeanExample; +import com.baeldung.component.outsidescope.OutsideScopeExample; +import com.baeldung.component.scannedscope.ScannedScopeExample; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class ComponentUnitTest { + + @Autowired + private ApplicationContext applicationContext; + + @Test + public void givenInScopeComponents_whenSearchingInApplicationContext_thenFindThem() { + assertNotNull(applicationContext.getBean(ControllerExample.class)); + assertNotNull(applicationContext.getBean(ServiceExample.class)); + assertNotNull(applicationContext.getBean(RepositoryExample.class)); + assertNotNull(applicationContext.getBean(ComponentExample.class)); + assertNotNull(applicationContext.getBean(CustomComponentExample.class)); + } + + @Test + public void givenOutsideScopeComponent_whenSearchingInApplicationContext_thenFail() { + assertThrows(NoSuchBeanDefinitionException.class, () -> applicationContext.getBean(OutsideScopeExample.class)); + } + + @Test + public void givenScannedScopeComponent_whenSearchingInApplicationContext_thenFindIt() { + assertNotNull(applicationContext.getBean(ScannedScopeExample.class)); + } + + @Test + public void givenBeanComponents_whenSearchingInApplicationContext_thenFindThem() { + assertNotNull(applicationContext.getBean(BeanExample.class)); + assertNotNull(applicationContext.getBean(OutsideScopeBeanExample.class)); + } + + @Test + public void givenAmbiguousBeanSetToB_whenSearchingInApplicationContext_thenFindImplB() { + AmbiguousBean ambiguousBean = applicationContext.getBean(AmbiguousBean.class); + assertNotNull(ambiguousBean); + assertTrue(ambiguousBean instanceof BeanImplB); + } +} \ No newline at end of file diff --git a/spring-core-5/src/test/resources/application.yml b/spring-core-5/src/test/resources/application.yml new file mode 100644 index 0000000000..da23e59c24 --- /dev/null +++ b/spring-core-5/src/test/resources/application.yml @@ -0,0 +1 @@ +ambiguous-bean: 'B' \ No newline at end of file From ba83b760d370fafb428e96b2346eb116cbacd028 Mon Sep 17 00:00:00 2001 From: mdabrowski-eu <57441874+mdabrowski-eu@users.noreply.github.com> Date: Sun, 14 Feb 2021 16:51:51 +0100 Subject: [PATCH 32/70] BAEL-4716 HashMap optimization (#10479) --- .../java/com/baeldung/map/hashing/Member.java | 6 ++ .../map/hashing/MemberWithBadHashing.java | 8 ++ .../map/hashing/MemberWithGuavaHashing.java | 18 +++++ .../baeldung/map/hashing/MemberWithId.java | 18 +++++ .../map/hashing/MemberWithIdAndName.java | 23 ++++++ .../map/hashing/MemberWithObjects.java | 19 +++++ .../baeldung/map/hashing/HashingUnitTest.java | 76 +++++++++++++++++++ 7 files changed, 168 insertions(+) create mode 100644 java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java create mode 100644 java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java create mode 100644 java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java create mode 100644 java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java create mode 100644 java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java create mode 100644 java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java create mode 100644 java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java new file mode 100644 index 0000000000..22b6a61d4d --- /dev/null +++ b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java @@ -0,0 +1,6 @@ +package com.baeldung.map.hashing; + +class Member { + Integer id; + String name; +} diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java new file mode 100644 index 0000000000..2a69291742 --- /dev/null +++ b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java @@ -0,0 +1,8 @@ +package com.baeldung.map.hashing; + +public class MemberWithBadHashing extends Member { + @Override + public int hashCode() { + return name.hashCode(); + } +} diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java new file mode 100644 index 0000000000..bb33ace0b7 --- /dev/null +++ b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java @@ -0,0 +1,18 @@ +package com.baeldung.map.hashing; + +import com.google.common.base.Charsets; +import com.google.common.hash.HashFunction; +import com.google.common.hash.Hashing; + +public class MemberWithGuavaHashing extends Member { + @Override + public int hashCode() { + HashFunction hashFunction = Hashing.murmur3_32(); + return hashFunction.newHasher() + .putInt(id) + .putString(name, Charsets.UTF_8) + .hash().hashCode(); + } + + +} diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java new file mode 100644 index 0000000000..5d82eb0cb7 --- /dev/null +++ b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java @@ -0,0 +1,18 @@ +package com.baeldung.map.hashing; + +public class MemberWithId extends Member { + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MemberWithId that = (MemberWithId) o; + + return id.equals(that.id); + } + + @Override + public int hashCode() { + return id; + } +} diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java new file mode 100644 index 0000000000..81ae48cf55 --- /dev/null +++ b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java @@ -0,0 +1,23 @@ +package com.baeldung.map.hashing; + +import java.util.Objects; + +public class MemberWithIdAndName extends Member { + public static final int PRIME = 31; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MemberWithObjects that = (MemberWithObjects) o; + return Objects.equals(id, that.id) && + Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + int result = id.hashCode(); + result = PRIME * result + (name == null ? 0 : name.hashCode()); + return result; + } +} diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java new file mode 100644 index 0000000000..b641035e4f --- /dev/null +++ b/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java @@ -0,0 +1,19 @@ +package com.baeldung.map.hashing; + +import java.util.Objects; + +public class MemberWithObjects extends Member { + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MemberWithObjects that = (MemberWithObjects) o; + return Objects.equals(id, that.id) && + Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java b/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java new file mode 100644 index 0000000000..d28a3b50b5 --- /dev/null +++ b/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.map.hashing; + +import com.google.common.base.Stopwatch; +import org.junit.jupiter.api.Test; + +import java.time.Duration; +import java.util.HashMap; +import java.util.SplittableRandom; +import java.util.function.Supplier; + +public class HashingUnitTest { + + public static final int SAMPLES = 1000000; + private SplittableRandom random = new SplittableRandom(); + + private String[] names = {"John", "Adam", "Suzie"}; + + @Test + void givenPrimitiveByteArrayKey_whenRetrievingFromMap_shouldRetrieveDifferentObjects() { + // bad hashing example is prohibitively slow for bigger samples +// Duration[] badHashing = testDuration(MemberWithBadHashing::new); + Duration[] withId = testDuration(MemberWithId::new); + Duration[] withObjects = testDuration(MemberWithObjects::new); + Duration[] withIdAndName = testDuration(MemberWithIdAndName::new); + +// System.out.println("Inserting with bad hashing:"); +// System.out.println(badHashing[0]); +// System.out.println("Getting with bad hashing:"); +// System.out.println(badHashing[1]); + + System.out.println("Inserting with id hashing:"); + System.out.println(withId[0]); + System.out.println("Getting with id hashing:"); + System.out.println(withId[1]); + + System.out.println("Inserting with id and name hashing:"); + System.out.println(withIdAndName[0]); + System.out.println("Getting with id and name hashing:"); + System.out.println(withIdAndName[1]); + + System.out.println("Inserting with Objects hashing:"); + System.out.println(withObjects[0]); + System.out.println("Getting with Objects hashing:"); + System.out.println(withObjects[1]); + } + + private String randomName() { + return names[random.nextInt(2)]; + } + + private Duration[] testDuration(Supplier factory) { + HashMap map = new HashMap<>(); + Stopwatch stopwatch = Stopwatch.createUnstarted(); + + stopwatch.start(); + for(int i = 0; i < SAMPLES; i++) { + T member = factory.get(); + member.id = i; + member.name = randomName(); + map.put(member, member.name); + } + stopwatch.stop(); + Duration elapsedInserting = stopwatch.elapsed(); + stopwatch.reset(); + + stopwatch.start(); + for (T key : map.keySet()) { + map.get(key); + } + stopwatch.stop(); + Duration elapsedGetting = stopwatch.elapsed(); + stopwatch.reset(); + + return new Duration[]{elapsedInserting, elapsedGetting}; + } +} From dc349a0c00361fdd9fd75e42f99a1a46f86df24d Mon Sep 17 00:00:00 2001 From: Azhwani Date: Sun, 14 Feb 2021 17:37:58 +0100 Subject: [PATCH 33/70] first commit --- .../NoConverterFoundApplication.java | 12 +++++ .../controller/StudentRestController.java | 21 ++++++++ .../boot/noconverterfound/model/Student.java | 53 +++++++++++++++++++ .../NoConverterFoundIntegrationTest.java | 50 +++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/NoConverterFoundApplication.java create mode 100644 spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java create mode 100644 spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/model/Student.java create mode 100644 spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/NoConverterFoundApplication.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/NoConverterFoundApplication.java new file mode 100644 index 0000000000..7abfa29bf2 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/NoConverterFoundApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.boot.noconverterfound; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class NoConverterFoundApplication { + + public static void main(String[] args) { + SpringApplication.run(NoConverterFoundApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java new file mode 100644 index 0000000000..21cb98710d --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java @@ -0,0 +1,21 @@ +package com.baeldung.boot.noconverterfound.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.boot.noconverterfound.model.Student; + +@RestController +@RequestMapping(value = "/api") +public class StudentRestController { + + @GetMapping("/student/{id}") + public ResponseEntity get(@PathVariable("id") int id) { + // Custom logic + return ResponseEntity.ok(new Student(id, "John", "Wiliams", "AA")); + } + +} diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/model/Student.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/model/Student.java new file mode 100644 index 0000000000..94ece02f8f --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/model/Student.java @@ -0,0 +1,53 @@ +package com.baeldung.boot.noconverterfound.model; + +public class Student { + + private int id; + private String firstName; + private String lastName; + private String grade; + + public Student() { + + } + + public Student(int id, String firstName, String lastName, String grade) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.grade = grade; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getGrade() { + return grade; + } + + public void setGrade(String grade) { + this.grade = grade; + } + +} diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java new file mode 100644 index 0000000000..3304a33957 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java @@ -0,0 +1,50 @@ +package com.baeldung.boot.noconverterfound; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.boot.noconverterfound.controller.StudentRestController; + +@RunWith(SpringRunner.class) +@WebMvcTest(StudentRestController.class) +public class NoConverterFoundIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void whenGettersNotDefined_thenThrowException() throws Exception { + + String url = "/api/student/1"; + + this.mockMvc.perform(get(url)) + .andExpect(status().isInternalServerError()) + .andExpect(result -> assertThat(result.getResolvedException()) + .isInstanceOf(HttpMessageNotWritableException.class)) + .andExpect(result -> assertThat(result.getResolvedException().getMessage()) + .contains("No converter found for return value of type")); + + } + + @Test + public void whenGettersAreDefined_thenReturnObject() throws Exception { + + String url = "/api/student/2"; + + this.mockMvc.perform(get(url)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.firstName").value("John")); + + } + +} From 7630f9dd91c8b8ce252455380d990802dbc8eaa7 Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Mon, 15 Feb 2021 16:25:11 +0000 Subject: [PATCH 34/70] BAEL-4672 changed file path to be placeholder for JMEter file axtraction script --- jmeter/src/main/resources/FileExtractionExample.jmx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmeter/src/main/resources/FileExtractionExample.jmx b/jmeter/src/main/resources/FileExtractionExample.jmx index e2047d0528..961b6f143f 100644 --- a/jmeter/src/main/resources/FileExtractionExample.jmx +++ b/jmeter/src/main/resources/FileExtractionExample.jmx @@ -57,7 +57,7 @@ false - FileWriter fWriter = new FileWriter("/Users/liamgarvie/Documents/result.txt", true); + FileWriter fWriter = new FileWriter("/result.txt", true); BufferedWriter buff = new BufferedWriter(fWriter); buff.write("Response Code : " + ctx.getPreviousResult().getResponseCode()); From dd0ef1d9c382f3d03c85cb25608a5743441c9063 Mon Sep 17 00:00:00 2001 From: Simone Cusimano Date: Mon, 15 Feb 2021 19:35:32 +0100 Subject: [PATCH 35/70] Convert to Maven project and add modules to parent --- spring-boot-modules/pom.xml | 1 + .../spring-boot-mvc-jersey/README.md | 8 + .../spring-boot-mvc-jersey/pom.xml | 23 +++ .../spring-boot-jersey/build.gradle | 22 --- .../gradle/wrapper/gradle-wrapper.properties | 5 - .../spring-boot-jersey/gradlew | 184 ------------------ .../spring-boot-jersey/gradlew.bat | 89 --------- .../spring-boot-jersey/pom.xml | 39 ++++ .../spring-boot-jersey/settings.gradle | 1 - .../spring-boot-mvc/build.gradle | 22 --- .../gradle/wrapper/gradle-wrapper.properties | 5 - .../spring-boot-mvc/gradlew | 184 ------------------ .../spring-boot-mvc/gradlew.bat | 89 --------- .../spring-boot-mvc/pom.xml | 39 ++++ .../spring-boot-mvc/settings.gradle | 1 - 15 files changed, 110 insertions(+), 602 deletions(-) create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/README.md create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/pom.xml delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat create mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml delete mode 100644 spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index ee088c357a..efe2c1ecc9 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -54,6 +54,7 @@ spring-boot-mvc-2 spring-boot-mvc-3 spring-boot-mvc-birt + spring-boot-mvc-jersey spring-boot-nashorn spring-boot-parent spring-boot-performance diff --git a/spring-boot-modules/spring-boot-mvc-jersey/README.md b/spring-boot-modules/spring-boot-mvc-jersey/README.md new file mode 100644 index 0000000000..07f9e78ea6 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/README.md @@ -0,0 +1,8 @@ +## Spring Boot Admin + +This module contains articles about Spring Boot: JAX-RS vs Spring + + +### Relevant Articles: + +- [REST API: JAX-RS vs Spring](https://www.baeldung.com/TBD) diff --git a/spring-boot-modules/spring-boot-mvc-jersey/pom.xml b/spring-boot-modules/spring-boot-mvc-jersey/pom.xml new file mode 100644 index 0000000000..ab117c4d2e --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + ../ + + + spring-boot-mvc-jersey + 0.0.1-SNAPSHOT + pom + + spring-boot-mvc-jersey + + + spring-boot-jersey + spring-boot-mvc + + diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle deleted file mode 100644 index e906adec44..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -plugins { - id 'org.springframework.boot' version '2.4.2' - id 'io.spring.dependency-management' version '1.0.11.RELEASE' - id 'java' -} - -group = 'com.baeldung.boot' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '15' - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-jersey' - testImplementation 'org.springframework.boot:spring-boot-starter-test' -} - -test { - useJUnitPlatform() -} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 4d9ca16491..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew deleted file mode 100644 index 8f8904743c..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ]; do - ls=$(ls -ld "$PRG") - link=$(expr "$ls" : '.*-> \(.*\)$') - if expr "$link" : '/.*' >/dev/null; then - PRG="$link" - else - PRG=$(dirname "$PRG")"/$link" - fi -done -SAVED="$(pwd)" -cd "$(dirname \"$PRG\")/" >/dev/null -APP_HOME="$(pwd -P)" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=$(basename "$0") - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn() { - echo "$*" -} - -die() { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$(uname)" in -CYGWIN*) - cygwin=true - ;; -Darwin*) - darwin=true - ;; -MINGW*) - msys=true - ;; -NONSTOP*) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ]; then - if [ -x "$JAVA_HOME/jre/sh/java" ]; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ]; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then - MAX_FD_LIMIT=$(ulimit -H -n) - if [ $? -eq 0 ]; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ]; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ]; then - APP_HOME=$(cygpath --path --mixed "$APP_HOME") - CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") - - JAVACMD=$(cygpath --unix "$JAVACMD") - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) - SEP="" - for dir in $ROOTDIRSRAW; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ]; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@"; do - CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) - CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition - eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") - else - eval $(echo args$i)="\"$arg\"" - fi - i=$(expr $i + 1) - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save() { - for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml new file mode 100644 index 0000000000..39c13b0860 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.4.2 + + + + com.baeldung.boot + jersey + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-jersey + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle deleted file mode 100644 index 5ce50b489f..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'jersey' diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle deleted file mode 100644 index 577ce18653..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -plugins { - id 'org.springframework.boot' version '2.4.2' - id 'io.spring.dependency-management' version '1.0.11.RELEASE' - id 'java' -} - -group = 'com.baeldung.boot' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '15' - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - testImplementation 'org.springframework.boot:spring-boot-starter-test' -} - -test { - useJUnitPlatform() -} diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 4d9ca16491..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew deleted file mode 100644 index 8f8904743c..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ]; do - ls=$(ls -ld "$PRG") - link=$(expr "$ls" : '.*-> \(.*\)$') - if expr "$link" : '/.*' >/dev/null; then - PRG="$link" - else - PRG=$(dirname "$PRG")"/$link" - fi -done -SAVED="$(pwd)" -cd "$(dirname \"$PRG\")/" >/dev/null -APP_HOME="$(pwd -P)" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=$(basename "$0") - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn() { - echo "$*" -} - -die() { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$(uname)" in -CYGWIN*) - cygwin=true - ;; -Darwin*) - darwin=true - ;; -MINGW*) - msys=true - ;; -NONSTOP*) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ]; then - if [ -x "$JAVA_HOME/jre/sh/java" ]; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ]; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then - MAX_FD_LIMIT=$(ulimit -H -n) - if [ $? -eq 0 ]; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ]; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ]; then - APP_HOME=$(cygpath --path --mixed "$APP_HOME") - CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") - - JAVACMD=$(cygpath --unix "$JAVACMD") - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) - SEP="" - for dir in $ROOTDIRSRAW; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ]; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@"; do - CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) - CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition - eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") - else - eval $(echo args$i)="\"$arg\"" - fi - i=$(expr $i + 1) - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save() { - for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat deleted file mode 100644 index 107acd32c4..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml new file mode 100644 index 0000000000..d9c0868c8e --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.4.2 + + + + com.baeldung.boot + mvc + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle deleted file mode 100644 index 028442d0f5..0000000000 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'mvc' From 8f91e48a32f64324aca7049d1069f0e2c64043a2 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Mon, 15 Feb 2021 17:57:21 -0300 Subject: [PATCH 36/70] added include-message property (commented out as the other properties), and updated deprecated getErrorAttributes method (caused not including the message property) --- .../com/baeldung/web/config/MyCustomErrorAttributes.java | 5 +++-- spring-boot-rest/src/main/resources/application.properties | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/config/MyCustomErrorAttributes.java b/spring-boot-rest/src/main/java/com/baeldung/web/config/MyCustomErrorAttributes.java index 1948d5552f..5e776c0e29 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/config/MyCustomErrorAttributes.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/config/MyCustomErrorAttributes.java @@ -2,6 +2,7 @@ package com.baeldung.web.config; import java.util.Map; +import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.servlet.error.DefaultErrorAttributes; import org.springframework.stereotype.Component; import org.springframework.web.context.request.WebRequest; @@ -10,8 +11,8 @@ import org.springframework.web.context.request.WebRequest; public class MyCustomErrorAttributes extends DefaultErrorAttributes { @Override - public Map getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) { - Map errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace); + public Map getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { + Map errorAttributes = super.getErrorAttributes(webRequest, options); errorAttributes.put("locale", webRequest.getLocale() .toString()); errorAttributes.remove("error"); diff --git a/spring-boot-rest/src/main/resources/application.properties b/spring-boot-rest/src/main/resources/application.properties index 176deb4f49..5017eb2f0d 100644 --- a/spring-boot-rest/src/main/resources/application.properties +++ b/spring-boot-rest/src/main/resources/application.properties @@ -3,3 +3,4 @@ server.servlet.context-path=/spring-boot-rest ### Spring Boot default error handling configurations #server.error.whitelabel.enabled=false #server.error.include-stacktrace=always +#server.error.include-message=always From 14acea1f33d2fbc59300b44776dc22ade450b276 Mon Sep 17 00:00:00 2001 From: Gerardo Roza Date: Tue, 16 Feb 2021 11:45:17 -0300 Subject: [PATCH 37/70] enabled server.error.include-message for 'cause' field to get populated, and using boot properties in MyErrorController setup, plus avoding deprecated method that bypasses error properties' --- .../java/com/baeldung/web/config/MyErrorController.java | 8 ++++---- .../src/main/resources/application.properties | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java b/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java index cf3f9c4dbd..05150716f6 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/config/MyErrorController.java @@ -4,7 +4,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; -import org.springframework.boot.autoconfigure.web.ErrorProperties; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; import org.springframework.boot.web.servlet.error.ErrorAttributes; import org.springframework.http.HttpStatus; @@ -16,13 +16,13 @@ import org.springframework.web.bind.annotation.RequestMapping; @Component public class MyErrorController extends BasicErrorController { - public MyErrorController(ErrorAttributes errorAttributes) { - super(errorAttributes, new ErrorProperties()); + public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties) { + super(errorAttributes, serverProperties.getError()); } @RequestMapping(produces = MediaType.APPLICATION_XML_VALUE) public ResponseEntity> xmlError(HttpServletRequest request) { - Map body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.APPLICATION_XML)); + Map body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.APPLICATION_XML)); body.put("xmlkey", "the XML response is different!"); HttpStatus status = getStatus(request); return new ResponseEntity<>(body, status); diff --git a/spring-boot-rest/src/main/resources/application.properties b/spring-boot-rest/src/main/resources/application.properties index 5017eb2f0d..1e985feed9 100644 --- a/spring-boot-rest/src/main/resources/application.properties +++ b/spring-boot-rest/src/main/resources/application.properties @@ -3,4 +3,4 @@ server.servlet.context-path=/spring-boot-rest ### Spring Boot default error handling configurations #server.error.whitelabel.enabled=false #server.error.include-stacktrace=always -#server.error.include-message=always +server.error.include-message=always From 8ad06829931964305b451e85d95f66f6422a15f3 Mon Sep 17 00:00:00 2001 From: osser-sam <46674082+osser-sam@users.noreply.github.com> Date: Tue, 16 Feb 2021 22:55:41 +0530 Subject: [PATCH 38/70] JAVA-4338: Upgrade spring-5-reactive-client module (#10486) * JAVA-4338: Upgrade spring-5-reactive-client module * JAVA-4338: removed duplicate entry --- spring-5-reactive-client/README.md | 1 - spring-5-reactive-client/pom.xml | 1 - .../src/main/resources/application.properties | 4 +- .../WebClientLoggingIntegrationTest.java | 55 +++++++++---------- .../reactive/logging/netty/CustomLogger.java | 42 -------------- 5 files changed, 30 insertions(+), 73 deletions(-) delete mode 100644 spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/netty/CustomLogger.java diff --git a/spring-5-reactive-client/README.md b/spring-5-reactive-client/README.md index b247a1669b..154a3cab0b 100644 --- a/spring-5-reactive-client/README.md +++ b/spring-5-reactive-client/README.md @@ -8,7 +8,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles - [Logging Spring WebClient Calls](https://www.baeldung.com/spring-log-webclient-calls) - [Simultaneous Spring WebClient Calls](https://www.baeldung.com/spring-webclient-simultaneous-calls) -- [Logging Spring WebClient Calls](https://www.baeldung.com/spring-log-webclient-calls) - [Mocking a WebClient in Spring](https://www.baeldung.com/spring-mocking-webclient) - [Spring WebClient Filters](https://www.baeldung.com/spring-webclient-filters) - [Get List of JSON Objects with WebClient](https://www.baeldung.com/spring-webclient-json-list) diff --git a/spring-5-reactive-client/pom.xml b/spring-5-reactive-client/pom.xml index 5b773cc63f..7ae7ba6edd 100644 --- a/spring-5-reactive-client/pom.xml +++ b/spring-5-reactive-client/pom.xml @@ -176,7 +176,6 @@ 4.1 1.0.3 4.0.1 - 2.3.3.RELEASE diff --git a/spring-5-reactive-client/src/main/resources/application.properties b/spring-5-reactive-client/src/main/resources/application.properties index 2d93456aeb..05033054b1 100644 --- a/spring-5-reactive-client/src/main/resources/application.properties +++ b/spring-5-reactive-client/src/main/resources/application.properties @@ -1,3 +1,5 @@ logging.level.root=INFO -server.port=8081 \ No newline at end of file +server.port=8081 + +logging.level.reactor.netty.http.client.HttpClient=DEBUG \ No newline at end of file diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java index 95c63f267f..bb4e682481 100644 --- a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java +++ b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java @@ -1,13 +1,13 @@ package com.baeldung.reactive.logging; -import ch.qos.logback.classic.spi.LoggingEvent; -import ch.qos.logback.core.Appender; -import com.baeldung.reactive.logging.filters.LogFilters; -import com.baeldung.reactive.logging.netty.CustomLogger; -import com.fasterxml.jackson.databind.ObjectMapper; +import static com.baeldung.reactive.logging.jetty.RequestLogEnhancer.enhance; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import java.net.URI; -import lombok.AllArgsConstructor; -import lombok.Data; + import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.BeforeEach; @@ -17,14 +17,17 @@ import org.springframework.http.client.reactive.JettyClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; -import reactor.netty.channel.BootstrapHandlers; -import reactor.netty.http.client.HttpClient; -import static com.baeldung.reactive.logging.jetty.RequestLogEnhancer.enhance; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import com.baeldung.reactive.logging.filters.LogFilters; +import com.fasterxml.jackson.databind.ObjectMapper; + +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.Appender; +import io.netty.handler.logging.LogLevel; +import lombok.AllArgsConstructor; +import lombok.Data; +import reactor.netty.http.client.HttpClient; +import reactor.netty.transport.logging.AdvancedByteBufFormat; public class WebClientLoggingIntegrationTest { @@ -114,21 +117,17 @@ public class WebClientLoggingIntegrationTest { @Test public void givenNettyHttpClientWithCustomLogger_whenEndpointIsConsumed_thenRequestAndResponseBodyLogged() { + reactor.netty.http.client.HttpClient httpClient = HttpClient.create() + .wiretap("reactor.netty.http.client.HttpClient", LogLevel.DEBUG, AdvancedByteBufFormat.TEXTUAL); - reactor.netty.http.client.HttpClient httpClient = HttpClient - .create() - .tcpConfiguration( - tc -> tc.bootstrap( - b -> BootstrapHandlers.updateLogSupport(b, new CustomLogger(HttpClient.class)))); - WebClient - .builder() - .clientConnector(new ReactorClientHttpConnector(httpClient)) - .build() - .post() - .uri(sampleUrl) - .body(BodyInserters.fromObject(post)) - .exchange() - .block(); + WebClient.builder() + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .build() + .post() + .uri(sampleUrl) + .body(BodyInserters.fromObject(post)) + .exchange() + .block(); verify(nettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleResponseBody))); } diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/netty/CustomLogger.java b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/netty/CustomLogger.java deleted file mode 100644 index 9f2a4d127f..0000000000 --- a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/logging/netty/CustomLogger.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.baeldung.reactive.logging.netty; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.logging.LoggingHandler; -import java.nio.charset.Charset; - -import static io.netty.util.internal.PlatformDependent.allocateUninitializedArray; -import static java.lang.Math.max; -import static java.nio.charset.Charset.defaultCharset; - -public class CustomLogger extends LoggingHandler { - public CustomLogger(Class clazz) { - super(clazz); - } - - @Override - protected String format(ChannelHandlerContext ctx, String event, Object arg) { - if (arg instanceof ByteBuf) { - ByteBuf msg = (ByteBuf) arg; - return decode(msg, msg.readerIndex(), msg.readableBytes(), defaultCharset()); - } - return super.format(ctx, event, arg); - } - - private String decode(ByteBuf src, int readerIndex, int len, Charset charset) { - if (len != 0) { - byte[] array; - int offset; - if (src.hasArray()) { - array = src.array(); - offset = src.arrayOffset() + readerIndex; - } else { - array = allocateUninitializedArray(max(len, 1024)); - offset = 0; - src.getBytes(readerIndex, array, 0, len); - } - return new String(array, offset, len, charset); - } - return ""; - } -} From 540ca5df0b557c295f0486a146ffe8a3d498d404 Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Wed, 17 Feb 2021 00:20:14 +0530 Subject: [PATCH 39/70] JAVA-2395 Fixed compilation issue (#10496) Co-authored-by: 13400152 --- .../core-java-jpms/decoupling-pattern2/consumermodule/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml index e6b351b1b9..816f5cf9e8 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml @@ -17,7 +17,7 @@ com.baeldung.servicemodule - servicemodule + servicemodule2 ${servicemodule.version} @@ -41,4 +41,4 @@ 1.0 - \ No newline at end of file + From 8a2a384dfab95976e0699266ae12e976584a49eb Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Wed, 17 Feb 2021 13:09:26 +0530 Subject: [PATCH 40/70] BAEL-3595: Initial change for Multipart file upload (#10465) * BAEL-3595: Initial change for Multipart file upload * Corrected the name * BAEL-3595: Added Tests * Corrected the tests name * Uncommented the code for live test Co-authored-by: Amitabh Tiwari --- spring-cloud/spring-cloud-openfeign/pom.xml | 14 +++++- .../fileupload/config/FeignSupportConfig.java | 28 +++++++++++ .../fileupload/controller/FileController.java | 28 +++++++++++ .../fileupload/service/UploadClient.java | 15 ++++++ .../fileupload/service/UploadResource.java | 16 ++++++ .../fileupload/service/UploadService.java | 29 +++++++++++ .../src/main/resources/fileupload.txt | 0 .../OpenFeignFileUploadLiveTest.java | 50 +++++++++++++++++++ 8 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java create mode 100644 spring-cloud/spring-cloud-openfeign/src/main/resources/fileupload.txt create mode 100644 spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignFileUploadLiveTest.java diff --git a/spring-cloud/spring-cloud-openfeign/pom.xml b/spring-cloud/spring-cloud-openfeign/pom.xml index c1f3f2dc30..bdde46fe96 100644 --- a/spring-cloud/spring-cloud-openfeign/pom.xml +++ b/spring-cloud/spring-cloud-openfeign/pom.xml @@ -37,12 +37,24 @@ io.github.openfeign feign-okhttp - + org.springframework.boot spring-boot-starter-web + + + io.github.openfeign.form + feign-form + 3.8.0 + + + io.github.openfeign.form + feign-form-spring + 3.8.0 + + org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java new file mode 100644 index 0000000000..64ff21bb7d --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java @@ -0,0 +1,28 @@ +package com.baeldung.cloud.openfeign.fileupload.config; + +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.cloud.openfeign.support.SpringEncoder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Scope; +import org.springframework.web.client.RestTemplate; + +import feign.codec.Encoder; +import feign.form.spring.SpringFormEncoder; + +@Configuration +public class FeignSupportConfig { + @Bean + @Primary + @Scope("prototype") + public Encoder multipartFormEncoder() { + return new SpringFormEncoder(new SpringEncoder(new ObjectFactory() { + @Override + public HttpMessageConverters getObject() { + return new HttpMessageConverters(new RestTemplate().getMessageConverters()); + } + })); + } +} diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java new file mode 100644 index 0000000000..ebdf7ff6c8 --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/controller/FileController.java @@ -0,0 +1,28 @@ +package com.baeldung.cloud.openfeign.fileupload.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.baeldung.cloud.openfeign.fileupload.service.UploadService; + +@RestController +public class FileController { + + @Autowired + private UploadService service; + + @PostMapping(value = "/upload") + public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) { + return service.uploadFile(file); + } + + @PostMapping(value = "/upload-mannual-client") + public boolean handleFileUploadWithManualClient( + @RequestPart(value = "file") MultipartFile file) { + return service.uploadFileWithManualClient(file); + } + +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java new file mode 100644 index 0000000000..63d17130e9 --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadClient.java @@ -0,0 +1,15 @@ +package com.baeldung.cloud.openfeign.fileupload.service; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; + +import com.baeldung.cloud.openfeign.fileupload.config.FeignSupportConfig; + +@FeignClient(name = "file", url = "http://localhost:8081", configuration = FeignSupportConfig.class) +public interface UploadClient { + @PostMapping(value = "/upload-file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + String fileUpload(@RequestPart(value = "file") MultipartFile file); +} diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java new file mode 100644 index 0000000000..26e658a7f0 --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadResource.java @@ -0,0 +1,16 @@ +package com.baeldung.cloud.openfeign.fileupload.service; + +import org.springframework.web.multipart.MultipartFile; + +import feign.Headers; +import feign.Param; +import feign.RequestLine; +import feign.Response; + +public interface UploadResource { + + @RequestLine("POST /upload-file") + @Headers("Content-Type: multipart/form-data") + Response uploadFile(@Param("file") MultipartFile file); + +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java new file mode 100644 index 0000000000..7dd7f5a89c --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/service/UploadService.java @@ -0,0 +1,29 @@ +package com.baeldung.cloud.openfeign.fileupload.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import feign.Feign; +import feign.Response; +import feign.form.spring.SpringFormEncoder; + +@Service +public class UploadService { + private static final String HTTP_FILE_UPLOAD_URL = "http://localhost:8081"; + + @Autowired + private UploadClient client; + + public boolean uploadFileWithManualClient(MultipartFile file) { + UploadResource fileUploadResource = Feign.builder().encoder(new SpringFormEncoder()) + .target(UploadResource.class, HTTP_FILE_UPLOAD_URL); + Response response = fileUploadResource.uploadFile(file); + return response.status() == 200; + } + + public String uploadFile(MultipartFile file) { + return client.fileUpload(file); + } + +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-openfeign/src/main/resources/fileupload.txt b/spring-cloud/spring-cloud-openfeign/src/main/resources/fileupload.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignFileUploadLiveTest.java b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignFileUploadLiveTest.java new file mode 100644 index 0000000000..f558e07491 --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignFileUploadLiveTest.java @@ -0,0 +1,50 @@ +package com.baeldung.cloud.openfeign; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +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.mock.web.MockMultipartFile; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.multipart.MultipartFile; + +import com.baeldung.cloud.openfeign.fileupload.service.UploadService; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class OpenFeignFileUploadLiveTest { + + @Autowired + private UploadService uploadService; + + private static String FILE_NAME = "fileupload.txt"; + + @Test + public void whenFeignBuilder_thenFileUploadSuccess() throws IOException { + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + File file = new File(classloader.getResource(FILE_NAME).getFile()); + Assert.assertTrue(file.exists()); + FileInputStream input = new FileInputStream(file); + MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", + IOUtils.toByteArray(input)); + Assert.assertTrue(uploadService.uploadFileWithManualClient(multipartFile)); + } + + @Test + public void whenAnnotatedFeignClient_thenFileUploadSuccess() throws IOException { + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + File file = new File(classloader.getResource(FILE_NAME).getFile()); + Assert.assertTrue(file.exists()); + FileInputStream input = new FileInputStream(file); + MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", + IOUtils.toByteArray(input)); + String uploadFile = uploadService.uploadFile(multipartFile); + Assert.assertNotNull(uploadFile); + } +} From af040e54c6aad2082ba7aaa3c1ae3a86e11313ac Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Wed, 17 Feb 2021 15:21:11 +0000 Subject: [PATCH 41/70] BAEL-4672 removed link from README file for JMeter file extraction article --- jmeter/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/jmeter/README.md b/jmeter/README.md index 84677ad618..6963aebb7c 100644 --- a/jmeter/README.md +++ b/jmeter/README.md @@ -52,4 +52,3 @@ Enjoy it :) - [Intro to Performance Testing using JMeter](https://www.baeldung.com/jmeter) - [Configure Jenkins to Run and Show JMeter Tests](https://www.baeldung.com/jenkins-and-jmeter) -- [Write Extracted Data to a File Using JMeter](https://www.baeldung.com/jmeter-file-extraction) From 336ef8775dabc436a870ca64c2037004a52fa1a9 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 18 Feb 2021 04:31:49 +0800 Subject: [PATCH 42/70] Update README.md --- core-java-modules/core-java-collections-maps-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-maps-3/README.md b/core-java-modules/core-java-collections-maps-3/README.md index 918c81fe4b..8b84ecbf81 100644 --- a/core-java-modules/core-java-collections-maps-3/README.md +++ b/core-java-modules/core-java-collections-maps-3/README.md @@ -7,4 +7,5 @@ This module contains articles about Map data structures in Java. - [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps) - [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent) - [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap) +- [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2) From 540377c6a71f12c611ede93b18d9a74587763834 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 18 Feb 2021 04:33:47 +0800 Subject: [PATCH 43/70] Update README.md --- spring-security-modules/spring-5-security/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-modules/spring-5-security/README.md b/spring-security-modules/spring-5-security/README.md index 1917d347fb..bad99c22d4 100644 --- a/spring-security-modules/spring-5-security/README.md +++ b/spring-security-modules/spring-5-security/README.md @@ -11,3 +11,4 @@ This module contains articles about Spring Security 5 - [Guide to the AuthenticationManagerResolver in Spring Security](https://www.baeldung.com/spring-security-authenticationmanagerresolver) - [Manual Logout With Spring Security](https://www.baeldung.com/spring-security-manual-logout) - [How to Disable Spring Security Logout Redirects](https://www.baeldung.com/spring-security-disable-logout-redirects) +- [Prevent Cross-Site Scripting (XSS) in a Spring Application](https://www.baeldung.com/spring-prevent-xss) From 29ad493e56f83f1e3e7b13b106a67fb7ecf8a6ca Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 18 Feb 2021 04:35:13 +0800 Subject: [PATCH 44/70] Update README.md --- spring-cloud/spring-cloud-openfeign/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud/spring-cloud-openfeign/README.md b/spring-cloud/spring-cloud-openfeign/README.md index 735903db72..bcfd769d0c 100644 --- a/spring-cloud/spring-cloud-openfeign/README.md +++ b/spring-cloud/spring-cloud-openfeign/README.md @@ -2,3 +2,4 @@ - [Introduction to Spring Cloud OpenFeign](https://www.baeldung.com/spring-cloud-openfeign) - [Differences Between Netflix Feign and OpenFeign](https://www.baeldung.com/netflix-feign-vs-openfeign) +- [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload) From 98cd39ff75d06f477a1c208f857625e1080b8ec8 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 18 Feb 2021 04:36:48 +0800 Subject: [PATCH 45/70] Update README.md --- spring-boot-modules/spring-boot-runtime-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-runtime-2/README.md b/spring-boot-modules/spring-boot-runtime-2/README.md index f997f2473d..9f0d814d8d 100644 --- a/spring-boot-modules/spring-boot-runtime-2/README.md +++ b/spring-boot-modules/spring-boot-runtime-2/README.md @@ -3,4 +3,4 @@ This module contains articles about administering a Spring Boot runtime ### Relevant Articles: - - + - [Configure the Heap Size When Starting a Spring Boot Application](https://www.baeldung.com/spring-boot-heap-size) From a1bd29e9d9466e99d0f2e5bff2f69112dde6fd39 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Thu, 18 Feb 2021 04:38:05 +0800 Subject: [PATCH 46/70] Update README.md --- spring-core-5/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-core-5/README.md b/spring-core-5/README.md index 81669e46a7..4109faca67 100644 --- a/spring-core-5/README.md +++ b/spring-core-5/README.md @@ -4,4 +4,5 @@ This module contains articles about core Spring functionality ## Relevant Articles: -- More articles: [[<-- prev]](/spring-core-4) \ No newline at end of file +- [Spring @Component Annotation](https://www.baeldung.com/spring-component-annotation) +- More articles: [[<-- prev]](/spring-core-4) From e5b7e9c81ff3717e77b6796086012ec246bdd2a2 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Fri, 19 Feb 2021 17:01:58 +0330 Subject: [PATCH 47/70] Update "Java built-in Annotations" article --- .../baeldung/annotations/AnnotatedClass.java | 8 ++++++++ .../annotations/RetentionAnnotation.java | 12 ++++++++++++ .../annotations/AnnotatedClassUnitTest.java | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java create mode 100644 core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/RetentionAnnotation.java create mode 100644 core-java-modules/core-java-annotations/src/test/java/com/baeldung/annotations/AnnotatedClassUnitTest.java diff --git a/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java b/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java new file mode 100644 index 0000000000..7825b400df --- /dev/null +++ b/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +import javax.annotation.Generated; + +@RetentionAnnotation +@Generated("Avilable only on source code") +public class AnnotatedClass { +} diff --git a/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/RetentionAnnotation.java b/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/RetentionAnnotation.java new file mode 100644 index 0000000000..4591334dde --- /dev/null +++ b/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/RetentionAnnotation.java @@ -0,0 +1,12 @@ +package com.baeldung.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; + +@Target(TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface RetentionAnnotation { +} \ No newline at end of file diff --git a/core-java-modules/core-java-annotations/src/test/java/com/baeldung/annotations/AnnotatedClassUnitTest.java b/core-java-modules/core-java-annotations/src/test/java/com/baeldung/annotations/AnnotatedClassUnitTest.java new file mode 100644 index 0000000000..9bf0b78cbb --- /dev/null +++ b/core-java-modules/core-java-annotations/src/test/java/com/baeldung/annotations/AnnotatedClassUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.annotations; + +import org.junit.Test; + +import java.lang.annotation.Annotation; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class AnnotatedClassUnitTest { + + @Test + public void whenAnnotationRetentionPolicyRuntime_shouldAccess() { + AnnotatedClass anAnnotatedClass = new AnnotatedClass(); + Annotation[] annotations = anAnnotatedClass.getClass().getAnnotations(); + assertThat(annotations.length, is(1)); + } +} From e2e416552384ccf115eacacab8159583e0240096 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Fri, 19 Feb 2021 17:06:57 +0330 Subject: [PATCH 48/70] Fixed a typo --- .../src/main/java/com/baeldung/annotations/AnnotatedClass.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java b/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java index 7825b400df..d5d9c88388 100644 --- a/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java +++ b/core-java-modules/core-java-annotations/src/main/java/com/baeldung/annotations/AnnotatedClass.java @@ -3,6 +3,6 @@ package com.baeldung.annotations; import javax.annotation.Generated; @RetentionAnnotation -@Generated("Avilable only on source code") +@Generated("Available only on source code") public class AnnotatedClass { } From c29b355b029c203e3f201f577359435d6dc700f6 Mon Sep 17 00:00:00 2001 From: Amitabh Tiwari Date: Sat, 20 Feb 2021 04:47:31 +0530 Subject: [PATCH 49/70] Bael 4804 config update (#10505) * Removed the configuration annotation * Removed @confiuration Co-authored-by: Amitabh Tiwari --- .../openfeign/fileupload/config/FeignSupportConfig.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java index 64ff21bb7d..943134213a 100644 --- a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/fileupload/config/FeignSupportConfig.java @@ -4,19 +4,13 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.Scope; import org.springframework.web.client.RestTemplate; import feign.codec.Encoder; import feign.form.spring.SpringFormEncoder; -@Configuration public class FeignSupportConfig { @Bean - @Primary - @Scope("prototype") public Encoder multipartFormEncoder() { return new SpringFormEncoder(new SpringEncoder(new ObjectFactory() { @Override From 0fabae2d65f6a6303a1aee9b0444df28e2a77b8d Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Sat, 20 Feb 2021 11:13:45 +0000 Subject: [PATCH 50/70] changed name of JMeter test controller to remove 'test' language from production code --- .../{TestController.java => RetrieveUuidController.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename jmeter/src/main/java/com/baeldung/controller/{TestController.java => RetrieveUuidController.java} (85%) diff --git a/jmeter/src/main/java/com/baeldung/controller/TestController.java b/jmeter/src/main/java/com/baeldung/controller/RetrieveUuidController.java similarity index 85% rename from jmeter/src/main/java/com/baeldung/controller/TestController.java rename to jmeter/src/main/java/com/baeldung/controller/RetrieveUuidController.java index 6e286265d3..3a2c14fc4b 100644 --- a/jmeter/src/main/java/com/baeldung/controller/TestController.java +++ b/jmeter/src/main/java/com/baeldung/controller/RetrieveUuidController.java @@ -9,10 +9,10 @@ import java.util.UUID; import static java.lang.String.format; @RestController -public class TestController { +public class RetrieveUuidController { @GetMapping("/api/test") - public Response test() { + public Response uuid() { return new Response(format("Test message... %s.", UUID.randomUUID())); } } From 745f15f7f2c8623714ba0b79029b6903894fcdd6 Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Sat, 20 Feb 2021 11:18:09 +0000 Subject: [PATCH 51/70] changed uri for jmeter UUID controller --- .../java/com/baeldung/controller/RetrieveUuidController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmeter/src/main/java/com/baeldung/controller/RetrieveUuidController.java b/jmeter/src/main/java/com/baeldung/controller/RetrieveUuidController.java index 3a2c14fc4b..32265c0170 100644 --- a/jmeter/src/main/java/com/baeldung/controller/RetrieveUuidController.java +++ b/jmeter/src/main/java/com/baeldung/controller/RetrieveUuidController.java @@ -11,7 +11,7 @@ import static java.lang.String.format; @RestController public class RetrieveUuidController { - @GetMapping("/api/test") + @GetMapping("/api/uuid") public Response uuid() { return new Response(format("Test message... %s.", UUID.randomUUID())); } From 04475d1555db0827455c9aa74c2e7c10434b13f4 Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Sat, 20 Feb 2021 11:19:12 +0000 Subject: [PATCH 52/70] Updated JMeter tests to reflect UUID controller change --- jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java b/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java index 5ccbeb875b..537e27dc55 100644 --- a/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java +++ b/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java @@ -22,8 +22,8 @@ class JmeterIntegrationTest { } @Test - void whenCallingTestController_thenWeShouldRecieveRandomizedResponse() throws Exception { - MockHttpServletResponse response = mvc.perform(get("/api/test")) + void whenCallingUUIDController_thenWeShouldRecieveRandomizedResponse() throws Exception { + MockHttpServletResponse response = mvc.perform(get("/api/uuid")) .andDo(print()) .andExpect(status().isOk()) .andReturn() From 5832baecccd6ba6b7cbb9679b051018192137c11 Mon Sep 17 00:00:00 2001 From: freelansam <79205526+freelansam@users.noreply.github.com> Date: Sat, 20 Feb 2021 22:27:17 +0530 Subject: [PATCH 53/70] BAEL-3821: Add new section in "Spring redirect and forward" article (#10502) --- .../redirect/RedirectController.java | 8 +++++- .../redirect/RedirectParamController.java | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectParamController.java diff --git a/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java b/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java index 321f3be3ef..1d77a07bea 100644 --- a/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java +++ b/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java @@ -64,5 +64,11 @@ public class RedirectController { public ModelAndView redirectedPostToPost() { return new ModelAndView("redirection"); } - + + @RequestMapping(value="/forwardWithParams", method = RequestMethod.GET) + public ModelAndView forwardWithParams(HttpServletRequest request) { + request.setAttribute("param1", "one"); + request.setAttribute("param2", "two"); + return new ModelAndView("forward:/forwardedWithParams"); + } } \ No newline at end of file diff --git a/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectParamController.java b/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectParamController.java new file mode 100644 index 0000000000..abe268b435 --- /dev/null +++ b/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectParamController.java @@ -0,0 +1,25 @@ +package com.baeldung.sampleapp.web.controller.redirect; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.springframework.web.servlet.view.RedirectView; + +@Controller +@RequestMapping("/") +public class RedirectParamController { + + @RequestMapping(value = "/forwardedWithParams", method = RequestMethod.GET) + public RedirectView forwardedWithParams(final RedirectAttributes redirectAttributes, HttpServletRequest request) { + + redirectAttributes.addAttribute("param1", request.getAttribute("param1")); + redirectAttributes.addAttribute("param2", request.getAttribute("param2")); + + redirectAttributes.addAttribute("attribute", "forwardedWithParams"); + return new RedirectView("redirectedUrl"); + + } +} \ No newline at end of file From b4174eb826c0799ebe708f04d4fbf73c218000d2 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Sun, 21 Feb 2021 17:11:10 +0530 Subject: [PATCH 54/70] JAVA-4294: Upgrade spring-data-rest module --- spring-data-rest/pom.xml | 3 +-- .../main/java/com/baeldung/halbrowser/config/RestConfig.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/spring-data-rest/pom.xml b/spring-data-rest/pom.xml index dd96182264..bfbd66a280 100644 --- a/spring-data-rest/pom.xml +++ b/spring-data-rest/pom.xml @@ -35,7 +35,7 @@ org.springframework.data - spring-data-rest-hal-browser + spring-data-rest-hal-explorer org.springframework.boot @@ -99,7 +99,6 @@ com.baeldung.books.SpringDataRestApplication 1.0 - 2.3.3.RELEASE \ No newline at end of file diff --git a/spring-data-rest/src/main/java/com/baeldung/halbrowser/config/RestConfig.java b/spring-data-rest/src/main/java/com/baeldung/halbrowser/config/RestConfig.java index 73f7e0f26a..a322bf0027 100644 --- a/spring-data-rest/src/main/java/com/baeldung/halbrowser/config/RestConfig.java +++ b/spring-data-rest/src/main/java/com/baeldung/halbrowser/config/RestConfig.java @@ -4,11 +4,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; -import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import org.springframework.validation.Validator; @Configuration -public class RestConfig extends RepositoryRestConfigurerAdapter { +public class RestConfig implements RepositoryRestConfigurer { //access to global validator @Autowired From 4e18d98258a7271c0af728db34dfcdbd10d670a2 Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Sun, 21 Feb 2021 20:05:30 +0000 Subject: [PATCH 55/70] BAEL-4672 updated JMeter readme to reflect changes in API format --- jmeter/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jmeter/README.md b/jmeter/README.md index 6963aebb7c..11351ffdda 100644 --- a/jmeter/README.md +++ b/jmeter/README.md @@ -36,12 +36,12 @@ Or create a new one via a POST: $ curl -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Dassi", "lastName" : "Orleando", "phoneNumber": "+237 545454545", "email": "mymail@yahoo.fr" }' localhost:8080/students ``` -### Available Test API +### Available UUID API You can view the test response using curl: ```bash -$ curl localhost:8080/api/test +$ curl localhost:8080/api/uuid ``` Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080) From bd4ff652f863e8a18c80f8e3fb93cec69e11f8e8 Mon Sep 17 00:00:00 2001 From: freelansam <79205526+freelansam@users.noreply.github.com> Date: Tue, 23 Feb 2021 00:19:12 +0530 Subject: [PATCH 56/70] JAVA-4340: Upgrade spring-boot-admin module (#10508) * JAVA-4340: Upgrade spring-boot-admin module * JAVA-4340: eviction policy correction --- .../spring-boot-admin-client/pom.xml | 2 +- .../spring-boot-admin-server/pom.xml | 5 +- .../SpringBootAdminServerApplication.java | 3 +- .../configs/HazelcastConfig.java | 48 +++++++++---------- 4 files changed, 27 insertions(+), 31 deletions(-) diff --git a/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml b/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml index eb40bfe8ea..f7a4b157e7 100644 --- a/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml +++ b/spring-boot-modules/spring-boot-admin/spring-boot-admin-client/pom.xml @@ -61,7 +61,7 @@ - 2.2.2 + 2.4.0 2.0.4.RELEASE diff --git a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml index 558aed8b26..bcec12a14c 100644 --- a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml +++ b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/pom.xml @@ -82,10 +82,9 @@ - 2.2.2 - 2.2.2 + 2.4.0 + 2.4.0 1.5.7 2.0.4.RELEASE - 2.3.3.RELEASE diff --git a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java index e934086cf4..5a713c7e8f 100644 --- a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java +++ b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java @@ -1,11 +1,12 @@ package com.baeldung.springbootadminserver; +import de.codecentric.boot.admin.server.config.AdminServerHazelcastAutoConfiguration; import de.codecentric.boot.admin.server.config.EnableAdminServer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableAdminServer -@SpringBootApplication +@SpringBootApplication(exclude = AdminServerHazelcastAutoConfiguration.class) public class SpringBootAdminServerApplication { public static void main(String[] args) { diff --git a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java index d38b0e933c..d53707c19a 100644 --- a/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java +++ b/spring-boot-modules/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java @@ -1,12 +1,13 @@ package com.baeldung.springbootadminserver.configs; import com.hazelcast.config.Config; +import com.hazelcast.config.EvictionConfig; import com.hazelcast.config.EvictionPolicy; import com.hazelcast.config.InMemoryFormat; import com.hazelcast.config.MapConfig; import com.hazelcast.config.MergePolicyConfig; import com.hazelcast.config.TcpIpConfig; -import com.hazelcast.map.merge.PutIfAbsentMapMergePolicy; +import com.hazelcast.spi.merge.PutIfAbsentMergePolicy; import java.util.Collections; @@ -16,32 +17,27 @@ import org.springframework.context.annotation.Configuration; @Configuration public class HazelcastConfig { - @Bean - public Config hazelcast() { - MapConfig eventStoreMap = new MapConfig("spring-boot-admin-event-store").setInMemoryFormat(InMemoryFormat.OBJECT) - .setBackupCount(1) - .setEvictionPolicy(EvictionPolicy.NONE) - .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMapMergePolicy.class.getName(), 100)); + @Bean + public Config hazelcast() { + MapConfig eventStoreMap = new MapConfig("spring-boot-admin-event-store") + .setInMemoryFormat(InMemoryFormat.OBJECT).setBackupCount(1) + .setEvictionConfig(new EvictionConfig().setEvictionPolicy(EvictionPolicy.NONE)) + .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMergePolicy.class.getName(), 100)); - MapConfig sentNotificationsMap = new MapConfig("spring-boot-admin-application-store").setInMemoryFormat(InMemoryFormat.OBJECT) - .setBackupCount(1) - .setEvictionPolicy(EvictionPolicy.LRU) - .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMapMergePolicy.class.getName(), 100)); + MapConfig sentNotificationsMap = new MapConfig("spring-boot-admin-application-store") + .setInMemoryFormat(InMemoryFormat.OBJECT).setBackupCount(1) + .setEvictionConfig(new EvictionConfig().setEvictionPolicy(EvictionPolicy.LRU)) + .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMergePolicy.class.getName(), 100)); - Config config = new Config(); - config.addMapConfig(eventStoreMap); - config.addMapConfig(sentNotificationsMap); - config.setProperty("hazelcast.jmx", "true"); + Config config = new Config(); + config.addMapConfig(eventStoreMap); + config.addMapConfig(sentNotificationsMap); + config.setProperty("hazelcast.jmx", "true"); - config.getNetworkConfig() - .getJoin() - .getMulticastConfig() - .setEnabled(false); - TcpIpConfig tcpIpConfig = config.getNetworkConfig() - .getJoin() - .getTcpIpConfig(); - tcpIpConfig.setEnabled(true); - tcpIpConfig.setMembers(Collections.singletonList("127.0.0.1")); - return config; - } + config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false); + TcpIpConfig tcpIpConfig = config.getNetworkConfig().getJoin().getTcpIpConfig(); + tcpIpConfig.setEnabled(true); + tcpIpConfig.setMembers(Collections.singletonList("127.0.0.1")); + return config; + } } From f6470356d2f449de83df5526d9925702bcc12689 Mon Sep 17 00:00:00 2001 From: Philippe Soares Date: Mon, 22 Feb 2021 14:37:46 -0500 Subject: [PATCH 57/70] #BAEL-4654 (#10450) * #BAEL-4654 * Fixing PR comments. --- docker/heap-sizing/Dockerfile | 4 ++ docker/heap-sizing/pom.xml | 61 +++++++++++++++++++ .../heapsizing/HeapSizingApplication.java | 19 ++++++ .../docker/heapsizing/PrintXmxXms.java | 36 +++++++++++ 4 files changed, 120 insertions(+) create mode 100644 docker/heap-sizing/Dockerfile create mode 100644 docker/heap-sizing/pom.xml create mode 100644 docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/HeapSizingApplication.java create mode 100644 docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/PrintXmxXms.java diff --git a/docker/heap-sizing/Dockerfile b/docker/heap-sizing/Dockerfile new file mode 100644 index 0000000000..c455e45c70 --- /dev/null +++ b/docker/heap-sizing/Dockerfile @@ -0,0 +1,4 @@ +FROM openjdk:8u92-jdk-alpine +COPY /src /src/ +RUN mkdir /app && ls /src && javac /src/main/java/com/baeldung/docker/heapsizing/PrintXmxXms.java -d /app +CMD java -version && java $JAVA_OPTS -cp /app com.baeldung.docker.heapsizing.PrintXmxXms \ No newline at end of file diff --git a/docker/heap-sizing/pom.xml b/docker/heap-sizing/pom.xml new file mode 100644 index 0000000000..a86a67fdcd --- /dev/null +++ b/docker/heap-sizing/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.4.2 + + + com.baeldung.docker + heap-sizing + 0.0.1-SNAPSHOT + heap-sizing + Demo project for Spring Boot + + 11 + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + heapsizing-demo + + + + + com.google.cloud.tools + jib-maven-plugin + 2.7.1 + + + + heapsizing-demo-jib + + + + + + + diff --git a/docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/HeapSizingApplication.java b/docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/HeapSizingApplication.java new file mode 100644 index 0000000000..00bee376c5 --- /dev/null +++ b/docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/HeapSizingApplication.java @@ -0,0 +1,19 @@ +package com.baeldung.docker.heapsizing; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import java.util.logging.Logger; + +import static com.baeldung.docker.heapsizing.PrintXmxXms.logMemory; + +@SpringBootApplication +public class HeapSizingApplication { + private static final Logger logger = Logger.getLogger(HeapSizingApplication.class.getName()); + + public static void main(String[] args) { + SpringApplication.run(HeapSizingApplication.class, args); + logMemory(logger); + } + +} diff --git a/docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/PrintXmxXms.java b/docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/PrintXmxXms.java new file mode 100644 index 0000000000..98f2f6455f --- /dev/null +++ b/docker/heap-sizing/src/main/java/com/baeldung/docker/heapsizing/PrintXmxXms.java @@ -0,0 +1,36 @@ +package com.baeldung.docker.heapsizing; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryPoolMXBean; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class PrintXmxXms { + + private static final Logger logger = Logger.getLogger(PrintXmxXms.class.getName()); + + public static void main(String[] args) { + logMemory(logger); + } + + /** + * We're reusing this method in HeapSizingApplication, therefore this method was extracted + * to avoid repetition. + */ + static void logMemory(Logger logger) { + float mb = 1024f * 1024f; + MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); + + // xmx controls the maximum size of the memory allocation pool, + // which includes the heap, the garbage collector's survivor space, and other pools. + float xmx = memoryBean.getHeapMemoryUsage().getMax() / mb; + float xms = memoryBean.getHeapMemoryUsage().getInit() / mb; + logger.log(Level.INFO, "Initial Memory (xms) : {0}mb", xms); + logger.log(Level.INFO, "Max Memory (xmx) : {0}mb", xmx); + + for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { + logger.log(Level.INFO, "Pool: {0} (type {1}) = {2}", new Object[]{ mp.getName(), mp.getType(), mp.getUsage().getMax() / mb }); + } + } +} From 47daf65bae6f7e9f09813270c4c20da72987d40c Mon Sep 17 00:00:00 2001 From: Liam Garvie Date: Tue, 23 Feb 2021 09:30:27 +0000 Subject: [PATCH 58/70] BAEL-4672 changed jmeter integration test's spacing to use spaces instead of tabs --- .../com/baeldung/JmeterIntegrationTest.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java b/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java index 537e27dc55..a1494416ef 100644 --- a/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java +++ b/jmeter/src/test/java/com/baeldung/JmeterIntegrationTest.java @@ -15,22 +15,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @SpringBootTest class JmeterIntegrationTest { - MockMvc mvc; + MockMvc mvc; - public JmeterIntegrationTest(WebApplicationContext wac) { - this.mvc = MockMvcBuilders.webAppContextSetup(wac).build(); - } + public JmeterIntegrationTest(WebApplicationContext wac) { + this.mvc = MockMvcBuilders.webAppContextSetup(wac).build(); + } - @Test - void whenCallingUUIDController_thenWeShouldRecieveRandomizedResponse() throws Exception { - MockHttpServletResponse response = mvc.perform(get("/api/uuid")) - .andDo(print()) - .andExpect(status().isOk()) - .andReturn() - .getResponse(); - - assertThat(response.getContentAsString()) - .contains("Test message..."); - } + @Test + void whenCallingUUIDController_thenWeShouldRecieveRandomizedResponse() throws Exception { + MockHttpServletResponse response = mvc.perform(get("/api/uuid")) + .andDo(print()) + .andExpect(status().isOk()) + .andReturn() + .getResponse(); + assertThat(response.getContentAsString()) + .contains("Test message..."); + } } From 300052acd4168eaf7e9e1f6211bfe1942d0d54e3 Mon Sep 17 00:00:00 2001 From: "Kent@lhind.hp.g5" Date: Sun, 21 Feb 2021 22:53:40 +0100 Subject: [PATCH 59/70] deque vs. stack article --- .../core-java-collections-4/pom.xml | 2 +- .../dequestack/ArrayLifoStack.java | 91 +++++++++++++++++++ .../collections/dequestack/LifoStack.java | 12 +++ .../dequestack/StackVsDequeUnitTest.java | 90 ++++++++++++++++++ 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/ArrayLifoStack.java create mode 100644 core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/LifoStack.java create mode 100644 core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/dequestack/StackVsDequeUnitTest.java diff --git a/core-java-modules/core-java-collections-4/pom.xml b/core-java-modules/core-java-collections-4/pom.xml index 0e3cabf40e..b4f8aa6320 100644 --- a/core-java-modules/core-java-collections-4/pom.xml +++ b/core-java-modules/core-java-collections-4/pom.xml @@ -25,7 +25,7 @@ - 3.18.0 + 3.19.0 diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/ArrayLifoStack.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/ArrayLifoStack.java new file mode 100644 index 0000000000..16fdec5b77 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/ArrayLifoStack.java @@ -0,0 +1,91 @@ +package com.baeldung.collections.dequestack; + +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.Iterator; + +public class ArrayLifoStack implements LifoStack { + private final Deque deque = new ArrayDeque<>(); + + @Override + public void push(E item) { + deque.addFirst(item); + } + + @Override + public E pop() { + return deque.removeFirst(); + } + + @Override + public E peek() { + return deque.peekFirst(); + } + + // implementing methods from the Collection interface + @Override + public int size() { + return deque.size(); + } + + @Override + public boolean isEmpty() { + return deque.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return deque.contains(o); + } + + @Override + public Iterator iterator() { + return deque.iterator(); + } + + @Override + public Object[] toArray() { + return deque.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return deque.toArray(a); + } + + @Override + public boolean add(E e) { + return deque.add(e); + } + + @Override + public boolean remove(Object o) { + return deque.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return deque.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return deque.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return deque.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return deque.retainAll(c); + } + + @Override + public void clear() { + deque.clear(); + } +} diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/LifoStack.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/LifoStack.java new file mode 100644 index 0000000000..11e07e3555 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/LifoStack.java @@ -0,0 +1,12 @@ +package com.baeldung.collections.dequestack; + +import java.util.Collection; + +public interface LifoStack extends Collection { + + E peek(); + + E pop(); + + void push(E item); +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/dequestack/StackVsDequeUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/dequestack/StackVsDequeUnitTest.java new file mode 100644 index 0000000000..ca3b0e8d54 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/dequestack/StackVsDequeUnitTest.java @@ -0,0 +1,90 @@ +package com.baeldung.collections.dequestack; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Iterator; +import java.util.Stack; + +import static org.assertj.core.api.Assertions.assertThat; + +class StackVsDequeUnitTest { + + @Test + void givenAStack_whenAccessByIndex_thenElementCanBeRead() { + Stack myStack = new Stack<>(); + myStack.push("I am the 1st element."); //index 0 + myStack.push("I am the 2nd element."); //index 1 + myStack.push("I am the 3rd element."); //index 2 + //access by index + assertThat(myStack.get(0)).isEqualTo("I am the 1st element."); + } + + @Test + void givenAStack_whenIterate_thenFromBottomToTop() { + Stack myStack = new Stack<>(); + myStack.push("I am at the bottom."); + myStack.push("I am in the middle."); + myStack.push("I am at the top."); + + Iterator it = myStack.iterator(); + + assertThat(it).toIterable().containsExactly( + "I am at the bottom.", + "I am in the middle.", + "I am at the top."); + } + + @Test + void givenAStack_whenAddOrRemoveByIndex_thenElementCanBeAddedOrRemoved() { + Stack myStack = new Stack<>(); + myStack.push("I am the 1st element."); + myStack.push("I am the 3rd element."); + + assertThat(myStack.size()).isEqualTo(2); + + //insert by index + myStack.add(1, "I am the 2nd element."); + assertThat(myStack.size()).isEqualTo(3); + assertThat(myStack.get(1)).isEqualTo("I am the 2nd element."); + //remove by index + myStack.remove(1); + assertThat(myStack.size()).isEqualTo(2); + } + + @Test + void givenADeque_whenAddOrRemoveLastElement_thenTheLastElementCanBeAddedOrRemoved() { + Deque myStack = new ArrayDeque<>(); + myStack.push("I am the 1st element."); + myStack.push("I am the 2nd element."); + myStack.push("I am the 3rd element."); + + assertThat(myStack.size()).isEqualTo(3); + + //insert element to the bottom of the stack + myStack.addLast("I am the NEW element."); + assertThat(myStack.size()).isEqualTo(4); + assertThat(myStack.peek()).isEqualTo("I am the 3rd element."); + + //remove element from the bottom of the stack + String removedStr = myStack.removeLast(); + assertThat(myStack.size()).isEqualTo(3); + assertThat(removedStr).isEqualTo("I am the NEW element."); + } + + @Test + void givenADeque_whenIterate_thenFromTopToBottom() { + Deque myStack = new ArrayDeque<>(); + myStack.push("I am at the bottom."); + myStack.push("I am in the middle."); + myStack.push("I am at the top."); + + Iterator it = myStack.iterator(); + + assertThat(it).toIterable().containsExactly( + "I am at the top.", + "I am in the middle.", + "I am at the bottom."); + } +} \ No newline at end of file From 9d7a90cab9c2676ccc378cb8d5da3334c0f9f033 Mon Sep 17 00:00:00 2001 From: sampadawagde Date: Tue, 23 Feb 2021 22:36:42 +0530 Subject: [PATCH 60/70] JAVA-4611: Update deprecations in spring-boot-rest module --- .../java/com/baeldung/web/controller/CustomerController.java | 4 ++-- .../ExamplePostControllerRequestIntegrationTest.java | 2 +- .../ExamplePostControllerResponseIntegrationTest.java | 2 +- .../com/baeldung/web/StudentControllerIntegrationTest.java | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/spring-boot-rest/src/main/java/com/baeldung/web/controller/CustomerController.java b/spring-boot-rest/src/main/java/com/baeldung/web/controller/CustomerController.java index 2b7dc1eee1..79d3b972ff 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/web/controller/CustomerController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/controller/CustomerController.java @@ -50,7 +50,7 @@ public class CustomerController { } Link link = linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)).withSelfRel(); - CollectionModel result = new CollectionModel<>(orders, link); + CollectionModel result = CollectionModel.of(orders, link); return result; } @@ -72,7 +72,7 @@ public class CustomerController { } Link link = linkTo(CustomerController.class).withSelfRel(); - CollectionModel result = new CollectionModel<>(allCustomers, link); + CollectionModel result = CollectionModel.of(allCustomers, link); return result; } diff --git a/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java index a277d5a685..bb84b88bd9 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java @@ -33,7 +33,7 @@ public class ExamplePostControllerRequestIntegrationTest { @Before public void preTest() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); mockMvc = MockMvcBuilders .standaloneSetup(exampleController) .build(); diff --git a/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java index f8c70b0f4a..efc3310812 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java @@ -34,7 +34,7 @@ public class ExamplePostControllerResponseIntegrationTest { @Before public void preTest() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); mockMvc = MockMvcBuilders .standaloneSetup(exampleController) .build(); diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/StudentControllerIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/StudentControllerIntegrationTest.java index 54ac69ebeb..d2d9181797 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/StudentControllerIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/StudentControllerIntegrationTest.java @@ -8,12 +8,10 @@ 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 org.springframework.web.server.MediaTypeNotSupportedStatusException; import com.baeldung.web.controller.students.Student; import com.fasterxml.jackson.databind.ObjectMapper; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; From ddaaffe55c80c8af3d3fc8b2c6ba14fdfbf64918 Mon Sep 17 00:00:00 2001 From: Adina Rolea Date: Tue, 23 Feb 2021 22:07:52 +0200 Subject: [PATCH 61/70] Feature/bael 4712 maven override parent config (#10459) * BAEL-4712: added maven example with override * BAEL-4712: added grandchild * BAEL-4712: updated PR * BAEL-4712: updated project structure * BAEL-4712: removed target * BAEL-4712: added extra property * BAEL-4712: added extra property * BAEL-4712: added extra property * BAEL-4712: added another example for combine attributes Co-authored-by: adina --- maven-modules/pom.xml | 1 + .../version-overriding-plugins/README.md | 1 + .../child-a/pom.xml | 36 ++++++++++++ .../child-b/pom.xml | 15 +++++ .../version-overriding-plugins/pom.xml | 55 +++++++++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 maven-modules/version-overriding-plugins/README.md create mode 100644 maven-modules/version-overriding-plugins/child-a/pom.xml create mode 100644 maven-modules/version-overriding-plugins/child-b/pom.xml create mode 100644 maven-modules/version-overriding-plugins/pom.xml diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index 86a7d5756c..c9a2b67a6c 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -27,6 +27,7 @@ versions-maven-plugin version-collision optional-dependencies + version-overriding-plugins diff --git a/maven-modules/version-overriding-plugins/README.md b/maven-modules/version-overriding-plugins/README.md new file mode 100644 index 0000000000..c7977135bc --- /dev/null +++ b/maven-modules/version-overriding-plugins/README.md @@ -0,0 +1 @@ +Use `` mvn help:effective-pom`` to see the final generated pom. \ No newline at end of file diff --git a/maven-modules/version-overriding-plugins/child-a/pom.xml b/maven-modules/version-overriding-plugins/child-a/pom.xml new file mode 100644 index 0000000000..780e1c4125 --- /dev/null +++ b/maven-modules/version-overriding-plugins/child-a/pom.xml @@ -0,0 +1,36 @@ + + + + version-overriding-plugins + com.baeldung + 0.0.1-SNAPSHOT + + 4.0.0 + pom + + child-a + + + + maven-resources-plugin + + + + child-a-resources + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/maven-modules/version-overriding-plugins/child-b/pom.xml b/maven-modules/version-overriding-plugins/child-b/pom.xml new file mode 100644 index 0000000000..05f127bc5c --- /dev/null +++ b/maven-modules/version-overriding-plugins/child-b/pom.xml @@ -0,0 +1,15 @@ + + + + version-overriding-plugins + com.baeldung + 0.0.1-SNAPSHOT + + 4.0.0 + + child-b + + + \ No newline at end of file diff --git a/maven-modules/version-overriding-plugins/pom.xml b/maven-modules/version-overriding-plugins/pom.xml new file mode 100644 index 0000000000..8d703ab568 --- /dev/null +++ b/maven-modules/version-overriding-plugins/pom.xml @@ -0,0 +1,55 @@ + + + + maven-modules + com.baeldung + 0.0.1-SNAPSHOT + + + 3.8.0 + + 4.0.0 + + version-overriding-plugins + pom + + + child-a + child-b + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin} + + + + + + maven-resources-plugin + + + + parent-resources + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + 512m + + + + + \ No newline at end of file From e5ad03c2bfff715a93c2f60a28012d4211976a73 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 24 Feb 2021 22:39:16 +0800 Subject: [PATCH 62/70] Update README.md --- spring-boot-modules/spring-boot-data-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-data-2/README.md b/spring-boot-modules/spring-boot-data-2/README.md index d5020ce354..29d9dafe66 100644 --- a/spring-boot-modules/spring-boot-data-2/README.md +++ b/spring-boot-modules/spring-boot-data-2/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper) +- [“HttpMessageNotWritableException: No converter found for return value of type”](https://www.baeldung.com/spring-no-converter-found) From 81096e08d4b5b9836fa1b015bcc6d9b699d53971 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 24 Feb 2021 22:41:55 +0800 Subject: [PATCH 63/70] Update README.md --- core-java-modules/core-java-lang-oop-generics/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-lang-oop-generics/README.md b/core-java-modules/core-java-lang-oop-generics/README.md index 9c9080ece3..720ba9dcfd 100644 --- a/core-java-modules/core-java-lang-oop-generics/README.md +++ b/core-java-modules/core-java-lang-oop-generics/README.md @@ -8,3 +8,4 @@ This module contains articles about generics in Java - [Raw Types in Java](https://www.baeldung.com/raw-types-java) - [Super Type Tokens in Java Generics](https://www.baeldung.com/java-super-type-tokens) - [Java Warning “unchecked conversion”](https://www.baeldung.com/java-unchecked-conversion) +- [Java Warning “Unchecked Cast”](https://www.baeldung.com/java-warning-unchecked-cast) From 4c17efbcc716c68fc5d789ebdd202210539c4bc4 Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 24 Feb 2021 22:44:48 +0800 Subject: [PATCH 64/70] Update README.md --- docker/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/README.md b/docker/README.md index ce7fe261c2..f1b4181e64 100644 --- a/docker/README.md +++ b/docker/README.md @@ -3,3 +3,4 @@ - [Introduction to Docker Compose](https://www.baeldung.com/docker-compose) - [Reusing Docker Layers with Spring Boot](https://www.baeldung.com/docker-layers-spring-boot) - [Running Spring Boot with PostgreSQL in Docker Compose](https://www.baeldung.com/spring-boot-postgresql-docker) +- [How To Configure Java Heap Size Inside a Docker Container](https://www.baeldung.com/ops/docker-jvm-heap-size) From 7575a64d7ec2bfd3629ea41cde2f362e539a60fa Mon Sep 17 00:00:00 2001 From: johnA1331 <53036378+johnA1331@users.noreply.github.com> Date: Wed, 24 Feb 2021 22:48:42 +0800 Subject: [PATCH 65/70] Update README.md --- maven-modules/version-overriding-plugins/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/maven-modules/version-overriding-plugins/README.md b/maven-modules/version-overriding-plugins/README.md index c7977135bc..1542692ca0 100644 --- a/maven-modules/version-overriding-plugins/README.md +++ b/maven-modules/version-overriding-plugins/README.md @@ -1 +1,5 @@ -Use `` mvn help:effective-pom`` to see the final generated pom. \ No newline at end of file +Use `` mvn help:effective-pom`` to see the final generated pom. + +### Relevant Articles: + +- [Override Maven Plugin Configuration from Parent](https://www.baeldung.com/maven-plugin-override-parent) From af3a534679153035047d69f6e037b20f4583f57e Mon Sep 17 00:00:00 2001 From: Simone Cusimano Date: Wed, 24 Feb 2021 18:34:42 +0100 Subject: [PATCH 66/70] Reformat pom.xml and rename artifactId --- .../spring-boot-jersey/pom.xml | 63 +++++++++---------- .../spring-boot-mvc/pom.xml | 63 +++++++++---------- 2 files changed, 62 insertions(+), 64 deletions(-) diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml index 39c13b0860..5756a27eca 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-jersey/pom.xml @@ -1,39 +1,38 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.4.2 - - + + org.springframework.boot + spring-boot-starter-parent + 2.4.2 + + - com.baeldung.boot - jersey - 0.0.1-SNAPSHOT + com.baeldung.boot + spring-boot-jersey + 0.0.1-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-jersey - + + + org.springframework.boot + spring-boot-starter-jersey + - - org.springframework.boot - spring-boot-starter-test - test - - + + org.springframework.boot + spring-boot-starter-test + test + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml index d9c0868c8e..69d355e574 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-jersey/spring-boot-mvc/pom.xml @@ -1,39 +1,38 @@ - - 4.0.0 + + 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.4.2 - - + + org.springframework.boot + spring-boot-starter-parent + 2.4.2 + + - com.baeldung.boot - mvc - 0.0.1-SNAPSHOT + com.baeldung.boot + spring-boot-mvc + 0.0.1-SNAPSHOT - - - org.springframework.boot - spring-boot-starter-web - + + + org.springframework.boot + spring-boot-starter-web + - - org.springframework.boot - spring-boot-starter-test - test - - + + org.springframework.boot + spring-boot-starter-test + test + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + From 6704dec346a7db639ee23968454634cb15ebd72b Mon Sep 17 00:00:00 2001 From: Krzysztof Woyke Date: Thu, 25 Feb 2021 23:45:12 +0100 Subject: [PATCH 67/70] JAVA-4397: Use random port for the GreetControllerRealIntegrationTest --- .../GreetControllerRealIntegrationTest.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java index 36751ba883..825520526e 100644 --- a/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java +++ b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java @@ -1,22 +1,25 @@ package com.baeldung.web.controller; import io.restassured.RestAssured; -import org.junit.Before; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.context.TestPropertySource; -import static io.restassured.RestAssured.DEFAULT_PORT; import static io.restassured.RestAssured.given; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -@SpringBootTest(webEnvironment = DEFINED_PORT) +@SpringBootTest(webEnvironment = RANDOM_PORT) @TestPropertySource(properties = {"spring.main.allow-bean-definition-overriding=true", "server.servlet.context-path=/"}) public class GreetControllerRealIntegrationTest { - @Before + @LocalServerPort + private int port; + + @BeforeEach public void setUp() { - RestAssured.port = DEFAULT_PORT; + RestAssured.port = port; } @Test From dc650c014c52c136d5c88e41c32f1a670fb3a363 Mon Sep 17 00:00:00 2001 From: Otto Dvalishvili <29176362+sparrowV@users.noreply.github.com> Date: Fri, 26 Feb 2021 08:00:21 +0400 Subject: [PATCH 68/70] Bael 4781: Introduction to ZeroCode (#10482) * small example of hexagonal architecture in java * Bael-4781: Introduction to ZeroCode * add readme * Revert "small example of hexagonal architecture in java" This reverts commit c0f96441 * refactoring * refactoring --- testing-modules/README.md | 3 - testing-modules/pom.xml | 7 +- testing-modules/zerocode/pom.xml | 102 ++++++++++++++++++ .../main/java/com/baeldung/zerocode/User.java | 31 ++++++ .../zerocode/ZerocodeApplication.java | 38 +++++++ .../zerocode/rest/UserEndpointIT.java | 18 ++++ .../test/resources/rest/user_create_test.json | 39 +++++++ .../src/test/resources/rest_api.properties | 3 + 8 files changed, 235 insertions(+), 6 deletions(-) delete mode 100644 testing-modules/README.md create mode 100644 testing-modules/zerocode/pom.xml create mode 100644 testing-modules/zerocode/src/main/java/com/baeldung/zerocode/User.java create mode 100644 testing-modules/zerocode/src/main/java/com/baeldung/zerocode/ZerocodeApplication.java create mode 100644 testing-modules/zerocode/src/test/java/com/baeldung/zerocode/rest/UserEndpointIT.java create mode 100644 testing-modules/zerocode/src/test/resources/rest/user_create_test.json create mode 100644 testing-modules/zerocode/src/test/resources/rest_api.properties diff --git a/testing-modules/README.md b/testing-modules/README.md deleted file mode 100644 index c6098d1210..0000000000 --- a/testing-modules/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Testing Modules - -This is an aggregator module containing multiple modules focused on testing libraries. diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index 0416423239..fd4a13d026 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -31,7 +31,7 @@ rest-assured rest-testing selenium-junit-testng - spring-testing + spring-testing spring-testing-2 test-containers testing-assertions @@ -41,9 +41,10 @@ junit-5-advanced xmlunit-2 junit-4 - testing-libraries - testing-libraries-2 + testing-libraries + testing-libraries-2 powermock + zerocode diff --git a/testing-modules/zerocode/pom.xml b/testing-modules/zerocode/pom.xml new file mode 100644 index 0000000000..9d765e6cb4 --- /dev/null +++ b/testing-modules/zerocode/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + testing-modules + com.baeldung + 1.0.0-SNAPSHOT + + + zerocode + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + + + + + org.jsmart + zerocode-tdd + 1.3.27 + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + it + + + + + pre-integration-test + + start + + + ${skip.it} + + + + post-integration-test + + stop + + + ${skip.it} + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.0.0-M5 + + ${skip.it} + + + + org.apache.maven.surefire + surefire-junit47 + 3.0.0-M5 + + + + + + integration-test + verify + + + + + + + + + UTF-8 + 8 + 8 + 2.4.2 + true + + + diff --git a/testing-modules/zerocode/src/main/java/com/baeldung/zerocode/User.java b/testing-modules/zerocode/src/main/java/com/baeldung/zerocode/User.java new file mode 100644 index 0000000000..3a2a853220 --- /dev/null +++ b/testing-modules/zerocode/src/main/java/com/baeldung/zerocode/User.java @@ -0,0 +1,31 @@ +package com.baeldung.zerocode; + +public class User { + private String id; + private String firstName; + private String lastName; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/testing-modules/zerocode/src/main/java/com/baeldung/zerocode/ZerocodeApplication.java b/testing-modules/zerocode/src/main/java/com/baeldung/zerocode/ZerocodeApplication.java new file mode 100644 index 0000000000..3218e97400 --- /dev/null +++ b/testing-modules/zerocode/src/main/java/com/baeldung/zerocode/ZerocodeApplication.java @@ -0,0 +1,38 @@ +package com.baeldung.zerocode; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +@SpringBootApplication +@RestController +@RequestMapping("/api/users") +public class ZerocodeApplication { + private List users = new ArrayList<>(); + + public static void main(String[] args) { + SpringApplication.run(ZerocodeApplication.class, args); + } + + @PostMapping + public ResponseEntity create(@RequestBody User user) { + if (!StringUtils.hasText(user.getFirstName())) { + return new ResponseEntity("firstName can't be empty!", HttpStatus.BAD_REQUEST); + } + if (!StringUtils.hasText(user.getLastName())) { + return new ResponseEntity("lastName can't be empty!", HttpStatus.BAD_REQUEST); + } + user.setId(UUID.randomUUID() + .toString()); + users.add(user); + return new ResponseEntity(user, HttpStatus.CREATED); + } + +} diff --git a/testing-modules/zerocode/src/test/java/com/baeldung/zerocode/rest/UserEndpointIT.java b/testing-modules/zerocode/src/test/java/com/baeldung/zerocode/rest/UserEndpointIT.java new file mode 100644 index 0000000000..cc461fd0fc --- /dev/null +++ b/testing-modules/zerocode/src/test/java/com/baeldung/zerocode/rest/UserEndpointIT.java @@ -0,0 +1,18 @@ +package com.baeldung.zerocode.rest; + +import org.jsmart.zerocode.core.domain.Scenario; +import org.jsmart.zerocode.core.domain.TargetEnv; +import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(ZeroCodeUnitRunner.class) +@TargetEnv("rest_api.properties") +public class UserEndpointIT { + + @Test + @Scenario("rest/user_create_test.json") + public void test_user_creation_endpoint() { + } + +} diff --git a/testing-modules/zerocode/src/test/resources/rest/user_create_test.json b/testing-modules/zerocode/src/test/resources/rest/user_create_test.json new file mode 100644 index 0000000000..0e8ee66196 --- /dev/null +++ b/testing-modules/zerocode/src/test/resources/rest/user_create_test.json @@ -0,0 +1,39 @@ +{ + "scenarioName": "test user creation endpoint", + "steps": [ + { + "name": "test_successful_creation", + "url": "/api/users", + "method": "POST", + "request": { + "body": { + "firstName": "John", + "lastName": "Doe" + } + }, + "verify": { + "status": 201, + "body": { + "id": "$NOT.NULL", + "firstName": "John", + "lastName": "Doe" + } + } + }, + { + "name": "test_firstname_validation", + "url": "/api/users", + "method": "POST", + "request": { + "body": { + "firstName": "", + "lastName": "Doe" + } + }, + "assertions": { + "status": 400, + "rawBody": "firstName can't be empty!" + } + } + ] +} diff --git a/testing-modules/zerocode/src/test/resources/rest_api.properties b/testing-modules/zerocode/src/test/resources/rest_api.properties new file mode 100644 index 0000000000..724042ade7 --- /dev/null +++ b/testing-modules/zerocode/src/test/resources/rest_api.properties @@ -0,0 +1,3 @@ +web.application.endpoint.host=http://localhost +web.application.endpoint.port=8080 +web.application.endpoint.context= \ No newline at end of file From 4ab767bec277e53065971619dc1e18db5a7f6455 Mon Sep 17 00:00:00 2001 From: Benedict Ayiko Date: Fri, 26 Feb 2021 11:41:58 +0300 Subject: [PATCH 69/70] BAEL-3439 - Add selector.wakeup() section (#10398) * Add selector.wakeup() section * Update SelectorTest.java * Update core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/SelectorTest.java * Update SelectorTest.java * Update and rename SelectorTest.java to SelectorUnitTest.java * Update SelectorUnitTest.java * Update and rename SelectorUnitTest.java to SelectorManualTest.java --- core-java-modules/core-java-nio-2/pom.xml | 9 ++- .../baeldung/selector/SelectorManualTest.java | 64 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/SelectorManualTest.java diff --git a/core-java-modules/core-java-nio-2/pom.xml b/core-java-modules/core-java-nio-2/pom.xml index 0c7c079406..7c4583476d 100644 --- a/core-java-modules/core-java-nio-2/pom.xml +++ b/core-java-modules/core-java-nio-2/pom.xml @@ -14,5 +14,12 @@ 0.0.1-SNAPSHOT ../ - + + + org.assertj + assertj-core + 3.6.1 + test + + \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/SelectorManualTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/SelectorManualTest.java new file mode 100644 index 0000000000..7a6c9e6eab --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/selector/SelectorManualTest.java @@ -0,0 +1,64 @@ +package com.baeldung.selector; + +import org.junit.Test; +import java.io.IOException; +import java.nio.channels.Pipe; +import java.nio.channels.SelectableChannel; +import java.nio.channels.Selector; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +import static org.assertj.core.api.Assertions.assertThat; + +import static java.nio.channels.SelectionKey.OP_READ; + +public class SelectorManualTest { + + @Test + public void whenWakeUpCalledOnSelector_thenBlockedThreadReturns() throws IOException, InterruptedException { + Pipe pipe = Pipe.open(); + + Selector selector = Selector.open(); + SelectableChannel channel = pipe.source(); + channel.configureBlocking(false); + channel.register(selector, OP_READ); + + List invocationStepsTracker = Collections.synchronizedList(new ArrayList<>()); + + CountDownLatch latch = new CountDownLatch(1); + + Thread thread = new Thread(() -> { + invocationStepsTracker.add(">> Count down"); + latch.countDown(); + try { + invocationStepsTracker.add(">> Start select"); + selector.select(); + invocationStepsTracker.add(">> End select"); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + invocationStepsTracker.add(">> Start await"); + thread.start(); + latch.await(); + invocationStepsTracker.add(">> End await"); + + invocationStepsTracker.add(">> Wakeup thread"); + + selector.wakeup(); + channel.close(); + + assertThat(invocationStepsTracker) + .containsExactly( + ">> Start await", + ">> Count down", + ">> Start select", + ">> End await", + ">> Wakeup thread", + ">> End select" + ); + } +} From 228e9a357cafc11b4274fee67df97f1aca59e91f Mon Sep 17 00:00:00 2001 From: Azhwani Date: Fri, 26 Feb 2021 19:23:09 +0100 Subject: [PATCH 70/70] Fix integration test --- .../noconverterfound/NoConverterFoundIntegrationTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java index 3304a33957..f8ded91e65 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java @@ -22,7 +22,8 @@ public class NoConverterFoundIntegrationTest { @Autowired private MockMvc mockMvc; - @Test + /* Remove Getters from Student class to successfully run this test case + * @Test public void whenGettersNotDefined_thenThrowException() throws Exception { String url = "/api/student/1"; @@ -35,6 +36,7 @@ public class NoConverterFoundIntegrationTest { .contains("No converter found for return value of type")); } + */ @Test public void whenGettersAreDefined_thenReturnObject() throws Exception {