diff --git a/akka-http/pom.xml b/akka-http/pom.xml index c0b460dd8e..c146e58b60 100644 --- a/akka-http/pom.xml +++ b/akka-http/pom.xml @@ -38,8 +38,6 @@ - UTF-8 - UTF-8 10.0.11 2.5.11 diff --git a/algorithms-miscellaneous-3/pom.xml b/algorithms-miscellaneous-3/pom.xml index 877e8bfefa..4b67a30abb 100644 --- a/algorithms-miscellaneous-3/pom.xml +++ b/algorithms-miscellaneous-3/pom.xml @@ -91,8 +91,6 @@ 4.3 28.0-jre 2.6.0 - 1.19 - 1.19 3.8.1 1.1.0 diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java index 0aaa1b6c23..60171220cd 100644 --- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java +++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java @@ -13,22 +13,22 @@ public class KadaneAlgorithm { int start = 0; int end = 0; - int maxSoFar = 0, maxEndingHere = 0; - + int maxSoFar = arr[0], maxEndingHere = arr[0]; for (int i = 0; i < size; i++) { if (arr[i] > maxEndingHere + arr[i]) { start = i; maxEndingHere = arr[i]; - } else + } else { maxEndingHere = maxEndingHere + arr[i]; + } if (maxSoFar < maxEndingHere) { maxSoFar = maxEndingHere; end = i; } } - logger.info("Found Maximum Subarray between {} and {}", start, end); + logger.info("Found Maximum Subarray between {} and {}", Math.min(start, end), end); return maxSoFar; } } diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java index 9bece56f5b..71531dcf59 100644 --- a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java +++ b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java @@ -9,11 +9,22 @@ class KadaneAlgorithmUnitTest { @Test void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturns6() { //given - int[] arr = new int[]{-3, 1, -8, 4, -1, 2, 1, -5, 5}; + int[] arr = new int[] { -3, 1, -8, 4, -1, 2, 1, -5, 5 }; //when KadaneAlgorithm algorithm = new KadaneAlgorithm(); int maxSum = algorithm.maxSubArraySum(arr); //then assertEquals(6, maxSum); } + + @Test + void givenArrayWithAllNegativeNumbersWhenMaximumSubarrayThenReturnsExpectedResult() { + //given + int[] arr = new int[] { -8, -7, -5, -4, -3, -1, -2 }; + //when + KadaneAlgorithm algorithm = new KadaneAlgorithm(); + int maxSum = algorithm.maxSubArraySum(arr); + //then + assertEquals(-1, maxSum); + } } \ No newline at end of file diff --git a/apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java b/apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerIntegrationTest.java similarity index 97% rename from apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java rename to apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerIntegrationTest.java index 992ea806c3..3d413e1939 100644 --- a/apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java +++ b/apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerIntegrationTest.java @@ -13,7 +13,7 @@ import java.util.Objects; import static org.junit.Assert.*; -public class AvroSerealizerDeSerealizerUnitTest { +public class AvroSerealizerDeSerealizerIntegrationTest { AvroSerealizer serealizer; AvroDeSerealizer deSerealizer; diff --git a/apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsUnitTest.java b/apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsIntegrationTest.java similarity index 95% rename from apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsUnitTest.java rename to apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsIntegrationTest.java index f9a06fd7b9..dbd777231c 100644 --- a/apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsUnitTest.java +++ b/apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsIntegrationTest.java @@ -17,7 +17,7 @@ import okhttp3.Request; import okhttp3.Response; @RunWith(MonoMeecrowave.Runner.class) -public class ArticleEndpointsUnitTest { +public class ArticleEndpointsIntegrationTest { @ConfigurationInject private Meecrowave.Builder config; diff --git a/apache-poi/README.md b/apache-poi/README.md index 599b21e063..d500787536 100644 --- a/apache-poi/README.md +++ b/apache-poi/README.md @@ -11,3 +11,4 @@ This module contains articles about Apache POI - [Get String Value of Excel Cell with Apache POI](https://www.baeldung.com/java-apache-poi-cell-string-value) - [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula) - [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas) +- [Insert a Row in Excel Using Apache POI](https://www.baeldung.com/apache-poi-insert-excel-row) diff --git a/aws-reactive/pom.xml b/aws-reactive/pom.xml index d4f0e5e231..6224ccbb99 100644 --- a/aws-reactive/pom.xml +++ b/aws-reactive/pom.xml @@ -100,7 +100,6 @@ - 1.8 2.2.1.RELEASE 2.10.27 diff --git a/core-groovy-2/pom.xml b/core-groovy-2/pom.xml index b1bfa19771..207c090615 100644 --- a/core-groovy-2/pom.xml +++ b/core-groovy-2/pom.xml @@ -115,7 +115,6 @@ maven-surefire-plugin - ${surefire.plugin.version} false @@ -186,7 +185,6 @@ 1.2.3 2.5.7 3.1.0 - 2.20.1 3.8.0 3.3.0-01 diff --git a/core-groovy-collections/pom.xml b/core-groovy-collections/pom.xml index 125dfca4c1..770bcc57d6 100644 --- a/core-groovy-collections/pom.xml +++ b/core-groovy-collections/pom.xml @@ -101,7 +101,6 @@ maven-surefire-plugin - ${surefire.plugin.version} false @@ -128,7 +127,6 @@ 2.4.0 1.1-groovy-2.4 1.6 - 2.20.1 diff --git a/core-java-modules/core-java-10/README.md b/core-java-modules/core-java-10/README.md index 11c2051816..9a110449bc 100644 --- a/core-java-modules/core-java-10/README.md +++ b/core-java-modules/core-java-10/README.md @@ -11,3 +11,4 @@ This module contains articles about Java 10 core features - [Copying Sets in Java](https://www.baeldung.com/java-copy-sets) - [Converting between a List and a Set in Java](https://www.baeldung.com/convert-list-to-set-and-set-to-list) - [Java IndexOutOfBoundsException “Source Does Not Fit in Dest”](https://www.baeldung.com/java-indexoutofboundsexception) +- [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection) diff --git a/core-java-modules/core-java-10/src/test/java/com/baeldung/java10/streams/StreamToImmutableJava10UnitTest.java b/core-java-modules/core-java-10/src/test/java/com/baeldung/java10/streams/StreamToImmutableJava10UnitTest.java new file mode 100644 index 0000000000..8b1ef54fd2 --- /dev/null +++ b/core-java-modules/core-java-10/src/test/java/com/baeldung/java10/streams/StreamToImmutableJava10UnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.java10.streams; + +import static java.util.stream.Collectors.toUnmodifiableList; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class StreamToImmutableJava10UnitTest { + + @Test + public void whenUsingCollectorsToUnmodifiableList_thenSuccess() { + List givenList = Arrays.asList("a", "b", "c"); + List result = givenList.stream() + .collect(toUnmodifiableList()); + + System.out.println(result.getClass()); + } +} diff --git a/core-java-modules/core-java-11/pom.xml b/core-java-modules/core-java-11/pom.xml index 2f7f5a6bcf..cdb3aab2c7 100644 --- a/core-java-modules/core-java-11/pom.xml +++ b/core-java-modules/core-java-11/pom.xml @@ -32,12 +32,12 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} provided @@ -105,7 +105,6 @@ 27.1-jre 3.11.1 benchmarks - 1.22 10.0.0 3.2.4 diff --git a/core-java-modules/core-java-arrays-guides/pom.xml b/core-java-modules/core-java-arrays-guides/pom.xml index df8639820d..a7c996cf7e 100644 --- a/core-java-modules/core-java-arrays-guides/pom.xml +++ b/core-java-modules/core-java-arrays-guides/pom.xml @@ -17,16 +17,18 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} + + + org.assertj + assertj-core + 3.19.0 + test - - - 1.19 - \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java index 5fd0385181..df7e0566ed 100644 --- a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java +++ b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/ListToArrayUnitTest.java @@ -2,7 +2,6 @@ package com.baeldung.genericarrays; import org.junit.Test; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; diff --git a/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/StreamToArrayUnitTest.java b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/StreamToArrayUnitTest.java new file mode 100644 index 0000000000..5dea901b25 --- /dev/null +++ b/core-java-modules/core-java-arrays-guides/src/test/java/com/baeldung/genericarrays/StreamToArrayUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.genericarrays; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.IntFunction; +import java.util.stream.Stream; + +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class StreamToArrayUnitTest { + + @Test + public void givenAStream_thenCanGetArrayOfObject() { + Object[] strings = Stream.of("A", "AAA", "B", "AAB", "C") + .filter(string -> string.startsWith("A")) + .toArray(); + + assertThat(strings).containsExactly("A", "AAA", "AAB"); + assertThat(strings).isNotInstanceOf(String[].class); + } + + @Test + public void givenAStream_thenCanGetArrayOfString() { + String[] strings = Stream.of("A", "AAA", "B", "AAB", "C") + .filter(string -> string.startsWith("A")) + .toArray(String[]::new); + + assertThat(strings).containsExactly("A", "AAA", "AAB"); + assertThat(strings).isInstanceOf(String[].class); + } + + @SuppressWarnings("unchecked") + @Test + public void givenAStream_whenConvertToOptional_thenCanGetArrayOfOptional() { + Stream> stream = Stream.of("A", "AAA", "B", "AAB", "C") + .filter(string -> string.startsWith("A")) + .map(Optional::of); + Optional[] strings = stream + .toArray(Optional[]::new); + + assertThat(strings).containsExactly(Optional.of("A"), + Optional.of("AAA"), + Optional.of("AAB")); + assertThat(strings).isInstanceOf(Optional[].class); + } + + @Test + public void givenAStream_whenConvertToOptional_thenCanGetArrayOfOptionalWithHelper() { + Optional[] strings = Stream.of("A", "AAA", "B", "AAB", "C") + .filter(string -> string.startsWith("A")) + .map(Optional::of) + .toArray(genericArray(Optional[]::new)); + + assertThat(strings).containsExactly(Optional.of("A"), + Optional.of("AAA"), + Optional.of("AAB")); + assertThat(strings).isInstanceOf(Optional[].class); + } + + @Test + public void whenInvalidUseOfGenericArray_thenIllegalCast() { + assertThatThrownBy(() -> { + ArrayList[] lists = Stream.of(singletonList("A")) + .toArray(genericArray(List[]::new)); + }).isInstanceOf(ClassCastException.class); + } + + @SuppressWarnings("unchecked") + private static IntFunction genericArray(IntFunction arrayCreator) { + return size -> (R[])arrayCreator.apply(size); + } +} diff --git a/core-java-modules/core-java-arrays-operations-basic/pom.xml b/core-java-modules/core-java-arrays-operations-basic/pom.xml index dcee6547a0..9157d9deb9 100644 --- a/core-java-modules/core-java-arrays-operations-basic/pom.xml +++ b/core-java-modules/core-java-arrays-operations-basic/pom.xml @@ -24,12 +24,12 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} @@ -68,7 +68,6 @@ 3.2.0 - 1.19 3.10.0 \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-sorting/pom.xml b/core-java-modules/core-java-arrays-sorting/pom.xml index 9b900c3de6..610582260b 100644 --- a/core-java-modules/core-java-arrays-sorting/pom.xml +++ b/core-java-modules/core-java-arrays-sorting/pom.xml @@ -31,12 +31,12 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} @@ -77,7 +77,6 @@ 3.2.0 28.2-jre - 1.19 3.10.0 \ No newline at end of file diff --git a/core-java-modules/core-java-char/pom.xml b/core-java-modules/core-java-char/pom.xml index 3691079482..078a829e00 100644 --- a/core-java-modules/core-java-char/pom.xml +++ b/core-java-modules/core-java-char/pom.xml @@ -25,17 +25,16 @@ org.openjdk.jmh jmh-core - ${openjdk.jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${openjdk.jmh.version} + ${jmh-generator.version} - 1.19 3.11.1 diff --git a/core-java-modules/core-java-collections-3/pom.xml b/core-java-modules/core-java-collections-3/pom.xml index 602fcf60f4..aa04d1cb24 100644 --- a/core-java-modules/core-java-collections-3/pom.xml +++ b/core-java-modules/core-java-collections-3/pom.xml @@ -24,7 +24,7 @@ org.openjdk.jmh jmh-core - ${openjdk.jmh.version} + ${jmh-core.version} org.assertj @@ -40,7 +40,6 @@ - 1.19 3.11.1 0.10 diff --git a/core-java-modules/core-java-collections-4/README.md b/core-java-modules/core-java-collections-4/README.md index 6e117c98b1..4fd77473d4 100644 --- a/core-java-modules/core-java-collections-4/README.md +++ b/core-java-modules/core-java-collections-4/README.md @@ -5,3 +5,4 @@ ### Relevant Articles: - [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap) +- [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack) diff --git a/core-java-modules/core-java-collections-list-3/pom.xml b/core-java-modules/core-java-collections-list-3/pom.xml index e1cf645c8a..d1d199ec3f 100644 --- a/core-java-modules/core-java-collections-list-3/pom.xml +++ b/core-java-modules/core-java-collections-list-3/pom.xml @@ -58,7 +58,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${jmh-core.version} + ${jmh-generator.version} diff --git a/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/primitive/PrimitivesListPerformance.java b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/primitive/PrimitivesListPerformance.java index bd37e5e74e..5dd1eaef09 100644 --- a/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/primitive/PrimitivesListPerformance.java +++ b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/primitive/PrimitivesListPerformance.java @@ -8,6 +8,7 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; @@ -18,12 +19,12 @@ import java.util.concurrent.TimeUnit; @State(Scope.Thread) public class PrimitivesListPerformance { - private List arrayList = new ArrayList<>(); - private TIntArrayList tList = new TIntArrayList(); - private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList(); - private IntArrayList fastUtilList = new IntArrayList(); + private List arrayList = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + private TIntArrayList tList = new TIntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); + private cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); + private IntArrayList fastUtilList = new IntArrayList(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); - private int getValue = 10; + private int getValue = 4; @Benchmark public boolean addArrayList() { 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 8b84ecbf81..530a9310c2 100644 --- a/core-java-modules/core-java-collections-maps-3/README.md +++ b/core-java-modules/core-java-collections-maps-3/README.md @@ -8,4 +8,5 @@ This module contains articles about Map data structures in Java. - [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) +- [Converting java.util.Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2) diff --git a/core-java-modules/core-java-collections/pom.xml b/core-java-modules/core-java-collections/pom.xml index e1219c4713..fe9cf57bfb 100644 --- a/core-java-modules/core-java-collections/pom.xml +++ b/core-java-modules/core-java-collections/pom.xml @@ -25,17 +25,16 @@ org.openjdk.jmh jmh-core - ${openjdk.jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${openjdk.jmh.version} + ${jmh-generator.version} - 1.19 3.11.1 diff --git a/core-java-modules/core-java-concurrency-advanced-2/pom.xml b/core-java-modules/core-java-concurrency-advanced-2/pom.xml index 2f374bffac..98f159a85f 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-2/pom.xml @@ -29,7 +29,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${jmh-generator-annprocess.version} + ${jmh-generator.version} @@ -51,8 +51,6 @@ - 1.19 - 1.19 3.6.1 diff --git a/core-java-modules/core-java-concurrency-collections-2/pom.xml b/core-java-modules/core-java-concurrency-collections-2/pom.xml index f9ee41f6d5..19d43aa7dd 100644 --- a/core-java-modules/core-java-concurrency-collections-2/pom.xml +++ b/core-java-modules/core-java-concurrency-collections-2/pom.xml @@ -23,12 +23,12 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} org.assertj @@ -39,7 +39,6 @@ - 1.21 28.2-jre 3.6.1 diff --git a/core-java-modules/core-java-concurrency-collections/src/test/java/com/baeldung/java/stream/ThreadPoolInParallelStreamIntegrationTest.java b/core-java-modules/core-java-concurrency-collections/src/test/java/com/baeldung/java/stream/ThreadPoolInParallelStreamIntegrationTest.java index 7ee849b0a2..ce96c107f8 100644 --- a/core-java-modules/core-java-concurrency-collections/src/test/java/com/baeldung/java/stream/ThreadPoolInParallelStreamIntegrationTest.java +++ b/core-java-modules/core-java-concurrency-collections/src/test/java/com/baeldung/java/stream/ThreadPoolInParallelStreamIntegrationTest.java @@ -21,14 +21,16 @@ public class ThreadPoolInParallelStreamIntegrationTest { long lastNum = 1_000_000; List aList = LongStream.rangeClosed(firstNum, lastNum).boxed().collect(Collectors.toList()); - ForkJoinPool customThreadPool = new ForkJoinPool(4); - long actualTotal = customThreadPool - .submit(() -> aList.parallelStream() - .reduce(0L, Long::sum)) - .get(); - assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal); + try { + long actualTotal = customThreadPool + .submit(() -> aList.parallelStream().reduce(0L, Long::sum)) + .get(); + assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal); + } finally { + customThreadPool.shutdown(); + } } @Test diff --git a/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java b/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java index caedd1747b..c20752639f 100644 --- a/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java +++ b/core-java-modules/core-java-io-conversions/src/test/java/com/baeldung/filetoinputstream/JavaXToInputStreamUnitTest.java @@ -5,12 +5,12 @@ import com.google.common.io.CharSource; import com.google.common.io.Files; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -import org.apache.commons.io.input.ReaderInputStream; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; +import java.nio.charset.StandardCharsets; public class JavaXToInputStreamUnitTest { protected final Logger logger = LoggerFactory.getLogger(getClass()); @@ -28,7 +28,7 @@ public class JavaXToInputStreamUnitTest { @Test public final void givenUsingGuava_whenConvertingStringToInputStream_thenCorrect() throws IOException { final String initialString = "text"; - final InputStream targetStream = new ReaderInputStream(CharSource.wrap(initialString).openStream()); + final InputStream targetStream = CharSource.wrap(initialString).asByteSource(StandardCharsets.UTF_8).openStream(); IOUtils.closeQuietly(targetStream); } diff --git a/core-java-modules/core-java-jvm/pom.xml b/core-java-modules/core-java-jvm/pom.xml index 08e536998c..17ff2f658f 100644 --- a/core-java-modules/core-java-jvm/pom.xml +++ b/core-java-modules/core-java-jvm/pom.xml @@ -77,7 +77,6 @@ 3.6.1 3.27.0-GA - 2.1.0.1 1.8.0 0.10 8.0.1 diff --git a/core-java-modules/core-java-lang-2/pom.xml b/core-java-modules/core-java-lang-2/pom.xml index d395e8efb1..9da76fa168 100644 --- a/core-java-modules/core-java-lang-2/pom.xml +++ b/core-java-modules/core-java-lang-2/pom.xml @@ -65,8 +65,6 @@ - 1.19 - 1.19 3.12.2 1.9.4 29.0-jre diff --git a/core-java-modules/core-java-lang-4/README.md b/core-java-modules/core-java-lang-4/README.md new file mode 100644 index 0000000000..77d14f0fc8 --- /dev/null +++ b/core-java-modules/core-java-lang-4/README.md @@ -0,0 +1,5 @@ +## Core Java Lang (Part 4) + +This module contains articles about core features in the Java language + +- [The Java final Keyword – Impact on Performance](https://www.baeldung.com/java-final-performance) diff --git a/core-java-modules/core-java-lang-4/pom.xml b/core-java-modules/core-java-lang-4/pom.xml new file mode 100644 index 0000000000..f00a9318f7 --- /dev/null +++ b/core-java-modules/core-java-lang-4/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + core-java-lang-4 + 0.1.0-SNAPSHOT + core-java-lang-4 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + ../ + + + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator.version} + test + + + + + core-java-lang-4 + + + src/main/resources + true + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/BenchmarkRunner.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/BenchmarkRunner.java new file mode 100644 index 0000000000..ee34114195 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/BenchmarkRunner.java @@ -0,0 +1,34 @@ +package com.baeldung.finalkeyword; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; + +import java.util.concurrent.TimeUnit; + +public class BenchmarkRunner { + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } + + @Benchmark + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @BenchmarkMode(Mode.AverageTime) + public static String concatNonFinalStrings() { + String x = "x"; + String y = "y"; + return x + y; + } + + @Benchmark + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @BenchmarkMode(Mode.AverageTime) + public static String concatFinalStrings() { + final String x = "x"; + final String y = "y"; + return x + y; + } + +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/ClassVariableFinal.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/ClassVariableFinal.java new file mode 100644 index 0000000000..1aeef76e58 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/ClassVariableFinal.java @@ -0,0 +1,19 @@ +package com.baeldung.finalkeyword; + +import java.io.Console; + +public class ClassVariableFinal { + + static final boolean doX = false; + static final boolean doY = true; + + public static void main(String[] args) { + Console console = System.console(); + if (doX) { + console.writer().println("x"); + } else if (doY) { + console.writer().println("y"); + } + } + +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/ClassVariableNonFinal.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/ClassVariableNonFinal.java new file mode 100644 index 0000000000..a6d83a66cb --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/finalkeyword/ClassVariableNonFinal.java @@ -0,0 +1,19 @@ +package com.baeldung.finalkeyword; + +import java.io.Console; + +public class ClassVariableNonFinal { + + static boolean doX = false; + static boolean doY = true; + + public static void main(String[] args) { + Console console = System.console(); + if (doX) { + console.writer().println("x"); + } else if (doY) { + console.writer().println("y"); + } + } + +} diff --git a/core-java-modules/core-java-lang-math-2/pom.xml b/core-java-modules/core-java-lang-math-2/pom.xml index e2cced4fbf..42704c784a 100644 --- a/core-java-modules/core-java-lang-math-2/pom.xml +++ b/core-java-modules/core-java-lang-math-2/pom.xml @@ -58,7 +58,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} @@ -83,7 +83,6 @@ 1.0.0-beta4 1.2.0 0.6.0 - 1.19 \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/classfile/Outer.java b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/classfile/Outer.java new file mode 100644 index 0000000000..489b85d12d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/main/java/com/baeldung/classfile/Outer.java @@ -0,0 +1,135 @@ +package com.baeldung.classfile; + +import org.apache.commons.lang3.StringUtils; +import com.baeldung.classfile.HelloWorld.HelloSomeone; + +public class Outer { + + // Static Nested class + static class StaticNested { + public String message() { + return "This is a static Nested Class"; + } + } + + // Non-static Nested class + class Nested { + public String message() { + return "This is a non-static Nested Class"; + } + } + + // Local class + public String message() { + class Local { + private String message() { + return "This is a Local Class within a method"; + } + } + Local local = new Local(); + return local.message(); + } + + // Local class within if clause + public String message(String name) { + if (StringUtils.isEmpty(name)) { + class Local { + private String message() { + return "This is a Local Class within if clause"; + } + } + Local local = new Local(); + return local.message(); + } else + return "Welcome to " + name; + } + + // Anonymous Inner class extending a class + public String greet() { + Outer anonymous = new Outer() { + @Override + public String greet() { + return "Running Anonymous Class..."; + } + }; + return anonymous.greet(); + } + + // Anonymous inner class implementing an interface + public String greet(String name) { + + HelloWorld helloWorld = new HelloWorld() { + @Override + public String greet(String name) { + return "Welcome to " + name; + } + + }; + return helloWorld.greet(name); + } + + // Anonymous inner class implementing nested interface + public String greetSomeone(String name) { + + HelloSomeone helloSomeOne = new HelloSomeone() { + @Override + public String greet(String name) { + return "Hello " + name; + } + + }; + return helloSomeOne.greet(name); + } + + // Nested interface within a class + interface HelloOuter { + public String hello(String name); + } + + // Enum within a class + enum Color { + RED, GREEN, BLUE; + } +} + +interface HelloWorld { + + public String greet(String name); + + // Nested class within an interface + class InnerClass implements HelloWorld { + @Override + public String greet(String name) { + return "Inner class within an interface"; + } + } + + // Nested interface within an interfaces + interface HelloSomeone { + public String greet(String name); + } + + // Enum within an interface + enum Directon { + NORTH, SOUTH, EAST, WEST; + } +} + +enum Level { + LOW, MEDIUM, HIGH; + +} + +enum Foods { + + DRINKS, EATS; + + // Enum within Enum + enum DRINKS { + APPLE_JUICE, COLA; + } + + enum EATS { + POTATO, RICE; + } +} diff --git a/core-java-modules/core-java-lang-oop-types/src/test/java/com/baeldung/classfile/OuterUnitTest.java b/core-java-modules/core-java-lang-oop-types/src/test/java/com/baeldung/classfile/OuterUnitTest.java new file mode 100644 index 0000000000..3ffe7d561a --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types/src/test/java/com/baeldung/classfile/OuterUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.classfile; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; +import com.baeldung.classfile.Outer.Nested; + +public class OuterUnitTest { + + @Test + public void when_static_nestedClass_then_verifyOutput() { + Outer.StaticNested nestedClass = new Outer.StaticNested(); + assertEquals("This is a static Nested Class", nestedClass.message()); + } + + @Test + public void when_nestedClass_then_verifyOutput() { + Outer outer = new Outer(); + Nested nestedClass = outer.new Nested(); + assertEquals("This is a non-static Nested Class", nestedClass.message()); + } + + @Test + public void when_localClass_then_verifyOutput() { + Outer outer = new Outer(); + assertEquals("This is a Local Class within a method", outer.message()); + } + + @Test + public void when_localClassInIfClause_then_verifyOutput() { + Outer outer = new Outer(); + assertEquals("Welcome to Baeldung", outer.message("Baeldung")); + assertEquals("This is a Local Class within if clause", outer.message("")); + } + + @Test + public void when_anonymousClass_then_verifyOutput() { + Outer outer = new Outer(); + assertEquals("Running Anonymous Class...", outer.greet()); + } + + @Test + public void when_anonymousClassHelloWorld_then_verifyOutput() { + Outer outer = new Outer(); + assertEquals("Welcome to Baeldung", outer.greet("Baeldung")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml index 575ccb0759..a6127f5fdd 100644 --- a/core-java-modules/core-java-optional/pom.xml +++ b/core-java-modules/core-java-optional/pom.xml @@ -67,8 +67,6 @@ 5.4.0.Final - 1.19 - 1.19 27.1-jre 3.10.0 3.1.1 diff --git a/core-java-modules/core-java-reflection-2/README.md b/core-java-modules/core-java-reflection-2/README.md index 9ed14f08dc..3195cddc42 100644 --- a/core-java-modules/core-java-reflection-2/README.md +++ b/core-java-modules/core-java-reflection-2/README.md @@ -4,3 +4,4 @@ - [Set Field Value With Reflection](https://www.baeldung.com/java-set-private-field-value) - [Checking If a Method is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static) - [Checking if a Java Class is ‘abstract’ Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract) +- [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method) diff --git a/core-java-modules/core-java-reflection-2/pom.xml b/core-java-modules/core-java-reflection-2/pom.xml index ea76ee8c98..02a806f87c 100644 --- a/core-java-modules/core-java-reflection-2/pom.xml +++ b/core-java-modules/core-java-reflection-2/pom.xml @@ -14,6 +14,15 @@ ../ + + + org.springframework + spring-test + ${spring.version} + test + + + core-java-reflection-2 @@ -40,5 +49,6 @@ 3.8.0 1.8 1.8 + 5.3.4 \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/privatemethods/LongArrayUtil.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/privatemethods/LongArrayUtil.java new file mode 100644 index 0000000000..03d8daabbf --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/access/privatemethods/LongArrayUtil.java @@ -0,0 +1,18 @@ +package com.baeldung.reflection.access.privatemethods; + +public class LongArrayUtil { + + public static int indexOf(long[] array, long target) { + return indexOf(array, target, 0, array.length); + } + + private static int indexOf(long[] array, long target, int start, int end) { + for (int i = start; i < end; i++) { + if (array[i] == target) { + return i; + } + } + return -1; + } + +} diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/access/privatemethods/InvokePrivateMethodsUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/access/privatemethods/InvokePrivateMethodsUnitTest.java new file mode 100644 index 0000000000..e98eb9ec7f --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/access/privatemethods/InvokePrivateMethodsUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.reflection.access.privatemethods; + +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import java.lang.reflect.Method; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class InvokePrivateMethodsUnitTest { + + private final long[] someLongArray = new long[] { 1L, 2L, 1L, 4L, 2L }; + + @Test + void whenSearchingForLongValueInSubsequenceUsingReflection_thenTheCorrectIndexOfTheValueIsReturned() throws Exception { + Method indexOfMethod = LongArrayUtil.class.getDeclaredMethod("indexOf", long[].class, long.class, int.class, int.class); + indexOfMethod.setAccessible(true); + + assertEquals(2, indexOfMethod.invoke(LongArrayUtil.class, someLongArray, 1L, 1, someLongArray.length), "The index should be 2."); + } + + @Test + void whenSearchingForLongValueInSubsequenceUsingSpring_thenTheCorrectIndexOfTheValueIsReturned() throws Exception { + int indexOfSearchTarget = ReflectionTestUtils.invokeMethod(LongArrayUtil.class, "indexOf", someLongArray, 1L, 1, someLongArray.length); + assertEquals(2, indexOfSearchTarget, "The index should be 2."); + } + +} diff --git a/core-java-modules/core-java-security-2/README.md b/core-java-modules/core-java-security-2/README.md index 9b99d624c9..3f9520b888 100644 --- a/core-java-modules/core-java-security-2/README.md +++ b/core-java-modules/core-java-security-2/README.md @@ -15,4 +15,5 @@ This module contains articles about core Java Security - [Security Context Basics: User, Subject and Principal](https://www.baeldung.com/security-context-basics) - [Java AES Encryption and Decryption](https://www.baeldung.com/java-aes-encryption-decryption) - [InvalidAlgorithmParameterException: Wrong IV Length](https://www.baeldung.com/java-invalidalgorithmparameter-exception) +- [The java.security.egd JVM Option](https://www.baeldung.com/java-security-egd) - More articles: [[<-- prev]](/core-java-modules/core-java-security) diff --git a/core-java-modules/core-java-streams-2/pom.xml b/core-java-modules/core-java-streams-2/pom.xml index 2a0a4348b0..323e01261f 100644 --- a/core-java-modules/core-java-streams-2/pom.xml +++ b/core-java-modules/core-java-streams-2/pom.xml @@ -47,7 +47,6 @@ - UTF-8 1.9 1.9 3.11.1 diff --git a/core-java-modules/core-java-streams-3/pom.xml b/core-java-modules/core-java-streams-3/pom.xml index cbb7366a7d..6597c999d8 100644 --- a/core-java-modules/core-java-streams-3/pom.xml +++ b/core-java-modules/core-java-streams-3/pom.xml @@ -49,8 +49,6 @@ 3.6.1 - - 2.22.1 diff --git a/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/streamvscollection/StreamVsCollectionExample.java b/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/streamvscollection/StreamVsCollectionExample.java new file mode 100644 index 0000000000..379d231bed --- /dev/null +++ b/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/streamvscollection/StreamVsCollectionExample.java @@ -0,0 +1,95 @@ +package com.baeldung.streams.streamvscollection; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class StreamVsCollectionExample { + + static ArrayList userNameSource = new ArrayList<>(); + + static { + userNameSource.add("john"); + userNameSource.add("smith"); + userNameSource.add("tom"); + userNameSource.add("rob"); + userNameSource.add("charlie"); + userNameSource.add("alfred"); + } + + public static Stream userNames() { + return userNameSource.stream(); + } + + public static List userNameList() { + return userNames().collect(Collectors.toList()); + } + + public static Set userNameSet() { + return userNames().collect(Collectors.toSet()); + } + + public static Map userNameMap() { + return userNames().collect(Collectors.toMap(u1 -> u1.toString(), u1 -> u1.toString())); + } + + public static Stream filterUserNames() { + return userNames().filter(i -> i.length() >= 4); + } + + public static Stream sortUserNames() { + return userNames().sorted(); + } + + public static Stream limitUserNames() { + return userNames().limit(3); + } + + public static Stream sortFilterLimitUserNames() { + return filterUserNames().sorted().limit(3); + } + + public static void printStream(Stream stream) { + stream.forEach(System.out::println); + } + + public static void modifyList() { + userNameSource.remove(2); + } + + public static Map modifyMap() { + Map userNameMap = userNameMap(); + userNameMap.put("bob", "bob"); + userNameMap.remove("alfred"); + + return userNameMap; + } + + public static void tryStreamTraversal() { + Stream userNameStream = userNames(); + userNameStream.forEach(System.out::println); + + try { + userNameStream.forEach(System.out::println); + } catch(IllegalStateException e) { + System.out.println("stream has already been operated upon or closed"); + } + } + + public static void main(String[] args) { + System.out.println(userNameMap()); + System.out.println(modifyMap()); + tryStreamTraversal(); + + Set set = userNames().collect(Collectors.toCollection(TreeSet::new)); + set.forEach(val -> System.out.println(val)); + + } + + +} diff --git a/core-java-modules/core-java-string-algorithms-2/pom.xml b/core-java-modules/core-java-string-algorithms-2/pom.xml index 2a84cebb4c..ae2685e742 100644 --- a/core-java-modules/core-java-string-algorithms-2/pom.xml +++ b/core-java-modules/core-java-string-algorithms-2/pom.xml @@ -34,7 +34,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${jmh-core.version} + ${jmh-generator.version} org.assertj diff --git a/core-java-modules/core-java-string-algorithms/pom.xml b/core-java-modules/core-java-string-algorithms/pom.xml index 6ba9ae7bb3..abafd10f2b 100644 --- a/core-java-modules/core-java-string-algorithms/pom.xml +++ b/core-java-modules/core-java-string-algorithms/pom.xml @@ -39,7 +39,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${jmh-core.version} + ${jmh-generator.version} com.vdurmont diff --git a/core-java-modules/multimodulemavenproject/pom.xml b/core-java-modules/multimodulemavenproject/pom.xml index dcf9f7311e..25f268f8b3 100644 --- a/core-java-modules/multimodulemavenproject/pom.xml +++ b/core-java-modules/multimodulemavenproject/pom.xml @@ -59,7 +59,6 @@ 3.8.0 1.9 1.9 - UTF-8 3.12.2 diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 2d342c4216..4cfe7fe34c 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -82,6 +82,7 @@ core-java-lang core-java-lang-2 core-java-lang-3 + core-java-lang-4 core-java-lang-math core-java-lang-math-2 core-java-lang-math-3 @@ -147,18 +148,6 @@ - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - - 2.22.2 5.6.2 diff --git a/custom-pmd/pom.xml b/custom-pmd/pom.xml index e0f38199ec..50bd16e2d5 100644 --- a/custom-pmd/pom.xml +++ b/custom-pmd/pom.xml @@ -45,7 +45,6 @@ - UTF-8 3.7.0 6.0.1 1.8 diff --git a/data-structures/src/main/java/com/baeldung/circularbuffer/CircularBuffer.java b/data-structures/src/main/java/com/baeldung/circularbuffer/CircularBuffer.java index 6b315265b4..cde07728ba 100644 --- a/data-structures/src/main/java/com/baeldung/circularbuffer/CircularBuffer.java +++ b/data-structures/src/main/java/com/baeldung/circularbuffer/CircularBuffer.java @@ -10,10 +10,8 @@ public class CircularBuffer { @SuppressWarnings("unchecked") public CircularBuffer(int capacity) { - this.capacity = (capacity < 1) ? DEFAULT_CAPACITY : capacity; - this.data = (E[]) new Object[capacity]; - + this.data = (E[]) new Object[this.capacity]; this.readSequence = 0; this.writeSequence = -1; } diff --git a/data-structures/src/main/java/com/baeldung/circularlinkedlist/CircularLinkedList.java b/data-structures/src/main/java/com/baeldung/circularlinkedlist/CircularLinkedList.java index 47368d7f15..cf18f0783e 100644 --- a/data-structures/src/main/java/com/baeldung/circularlinkedlist/CircularLinkedList.java +++ b/data-structures/src/main/java/com/baeldung/circularlinkedlist/CircularLinkedList.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; public class CircularLinkedList { - final Logger LOGGER = LoggerFactory.getLogger(CircularLinkedList.class); + final Logger logger = LoggerFactory.getLogger(CircularLinkedList.class); private Node head = null; private Node tail = null; @@ -42,24 +42,29 @@ public class CircularLinkedList { } public void deleteNode(int valueToDelete) { - Node currentNode = head; - - if (head != null) { - if (currentNode.value == valueToDelete) { - head = head.nextNode; - tail.nextNode = head; - } else { - do { - Node nextNode = currentNode.nextNode; - if (nextNode.value == valueToDelete) { - currentNode.nextNode = nextNode.nextNode; - break; - } - currentNode = currentNode.nextNode; - } while (currentNode != head); - } + if (head == null) { + return; } + do { + Node nextNode = currentNode.nextNode; + if (nextNode.value == valueToDelete) { + if (tail == head) { + head = null; + tail = null; + } else { + currentNode.nextNode = nextNode.nextNode; + if (head == nextNode) { + head = head.nextNode; + } + if (tail == nextNode) { + tail = currentNode; + } + } + break; + } + currentNode = nextNode; + } while (currentNode != head); } public void traverseList() { @@ -68,7 +73,7 @@ public class CircularLinkedList { if (head != null) { do { - LOGGER.info(currentNode.value + " "); + logger.info(currentNode.value + " "); currentNode = currentNode.nextNode; } while (currentNode != head); } diff --git a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java index 7469e8ba64..42cacbd3ea 100644 --- a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java +++ b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java @@ -148,48 +148,46 @@ public class BinaryTree { } } - public void traverseInOrderWithoutRecursion() { - Stack stack = new Stack(); + Stack stack = new Stack<>(); + Node current = root; + + while (current != null || !stack.isEmpty()) { + while (current != null) { + stack.push(current); + current = current.left; + } + + Node top = stack.pop(); + visit(top.value); + current = top.right; + } + } + + public void traversePreOrderWithoutRecursion() { + Stack stack = new Stack<>(); Node current = root; stack.push(root); - while(! stack.isEmpty()) { - while(current.left != null) { - current = current.left; - stack.push(current); - } + + while (current != null && !stack.isEmpty()) { current = stack.pop(); visit(current.value); - if(current.right != null) { - current = current.right; - stack.push(current); - } + + if (current.right != null) + stack.push(current.right); + + if (current.left != null) + stack.push(current.left); } } - public void traversePreOrderWithoutRecursion() { - Stack stack = new Stack(); - Node current = root; - stack.push(root); - while(! stack.isEmpty()) { - current = stack.pop(); - visit(current.value); - - if(current.right != null) - stack.push(current.right); - - if(current.left != null) - stack.push(current.left); - } - } - public void traversePostOrderWithoutRecursion() { - Stack stack = new Stack(); + Stack stack = new Stack<>(); Node prev = root; Node current = root; stack.push(root); - while (!stack.isEmpty()) { + while (current != null && !stack.isEmpty()) { current = stack.peek(); boolean hasChild = (current.left != null || current.right != null); boolean isPrevLastChild = (prev == current.right || (prev == current.left && current.right == null)); diff --git a/data-structures/src/test/java/com/baeldung/circularlinkedlist/CircularLinkedListUnitTest.java b/data-structures/src/test/java/com/baeldung/circularlinkedlist/CircularLinkedListUnitTest.java index 5b0573a1ce..23829df7e9 100644 --- a/data-structures/src/test/java/com/baeldung/circularlinkedlist/CircularLinkedListUnitTest.java +++ b/data-structures/src/test/java/com/baeldung/circularlinkedlist/CircularLinkedListUnitTest.java @@ -1,10 +1,10 @@ package com.baeldung.circularlinkedlist; +import org.junit.Test; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import org.junit.Test; - public class CircularLinkedListUnitTest { @Test @@ -23,7 +23,7 @@ public class CircularLinkedListUnitTest { } @Test - public void givenACircularLinkedList_WhenDeletingElements_ThenListDoesNotContainThoseElements() { + public void givenACircularLinkedList_WhenDeletingInOrderHeadMiddleTail_ThenListDoesNotContainThoseElements() { CircularLinkedList cll = createCircularLinkedList(); assertTrue(cll.containsNode(13)); @@ -39,6 +39,32 @@ public class CircularLinkedListUnitTest { assertFalse(cll.containsNode(46)); } + @Test + public void givenACircularLinkedList_WhenDeletingInOrderTailMiddleHead_ThenListDoesNotContainThoseElements() { + CircularLinkedList cll = createCircularLinkedList(); + + assertTrue(cll.containsNode(46)); + cll.deleteNode(46); + assertFalse(cll.containsNode(46)); + + assertTrue(cll.containsNode(1)); + cll.deleteNode(1); + assertFalse(cll.containsNode(1)); + + assertTrue(cll.containsNode(13)); + cll.deleteNode(13); + assertFalse(cll.containsNode(13)); + } + + @Test + public void givenACircularLinkedListWithOneNode_WhenDeletingElement_ThenListDoesNotContainTheElement() { + CircularLinkedList cll = new CircularLinkedList(); + cll.addNode(1); + cll.deleteNode(1); + assertFalse(cll.containsNode(1)); + } + + private CircularLinkedList createCircularLinkedList() { CircularLinkedList cll = new CircularLinkedList(); diff --git a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java index f99cb52ed7..e89557f21b 100644 --- a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java +++ b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java @@ -13,7 +13,7 @@ public class BinaryTreeUnitTest { BinaryTree bt = createBinaryTree(); - assertTrue(!bt.isEmpty()); + assertFalse(bt.isEmpty()); } @Test @@ -72,6 +72,7 @@ public class BinaryTreeUnitTest { @Test public void it_deletes_the_root() { + int value = 12; BinaryTree bt = new BinaryTree(); bt.add(value); @@ -91,6 +92,14 @@ public class BinaryTreeUnitTest { bt.traverseInOrderWithoutRecursion(); } + @Test + public void givenAnEmptyBinaryTree_WhenTraversingInOrderWithoutRecursion_ThenNoException() { + + BinaryTree empty = new BinaryTree(); + + empty.traverseInOrderWithoutRecursion(); + } + @Test public void givenABinaryTree_WhenTraversingPreOrder_ThenPrintValues() { @@ -101,6 +110,14 @@ public class BinaryTreeUnitTest { bt.traversePreOrderWithoutRecursion(); } + @Test + public void givenAnEmptyBinaryTree_WhenTraversingPreOrderWithoutRecursion_ThenNoException() { + + BinaryTree empty = new BinaryTree(); + + empty.traversePreOrderWithoutRecursion(); + } + @Test public void givenABinaryTree_WhenTraversingPostOrder_ThenPrintValues() { @@ -111,6 +128,14 @@ public class BinaryTreeUnitTest { bt.traversePostOrderWithoutRecursion(); } + @Test + public void givenAnEmptyBinaryTree_WhenTraversingPostOrderWithoutRecursion_ThenNoException() { + + BinaryTree empty = new BinaryTree(); + + empty.traversePostOrderWithoutRecursion(); + } + @Test public void givenABinaryTree_WhenTraversingLevelOrder_ThenPrintValues() { diff --git a/ddd-modules/mainapp/pom.xml b/ddd-modules/mainapp/pom.xml index 59d2ad7d3a..6b913df979 100644 --- a/ddd-modules/mainapp/pom.xml +++ b/ddd-modules/mainapp/pom.xml @@ -29,7 +29,6 @@ org.apache.maven.plugins maven-surefire-plugin - 2.16 true diff --git a/ddd-modules/pom.xml b/ddd-modules/pom.xml index 6ab1829198..376dad89e5 100644 --- a/ddd-modules/pom.xml +++ b/ddd-modules/pom.xml @@ -66,7 +66,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} 0 @@ -75,13 +74,10 @@ - UTF-8 - 9 9 3.8.1 - 2.22.2 1.0 diff --git a/ddd/pom.xml b/ddd/pom.xml index 7d03208802..41fccc7d5f 100644 --- a/ddd/pom.xml +++ b/ddd/pom.xml @@ -99,15 +99,6 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - - - - 1.0.1 diff --git a/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml index 6fdcae4f75..1ff5081343 100644 --- a/google-web-toolkit/pom.xml +++ b/google-web-toolkit/pom.xml @@ -97,7 +97,6 @@ maven-surefire-plugin - ${surefire.plugin.version} true @@ -113,12 +112,8 @@ 1.8 1.8 - - UTF-8 - UTF-8 2.8.2 1.0-rc-8 - 2.17 diff --git a/guava-modules/guava-collections-list/pom.xml b/guava-modules/guava-collections-list/pom.xml index cc52a5d48b..78a4aeb8ea 100644 --- a/guava-modules/guava-collections-list/pom.xml +++ b/guava-modules/guava-collections-list/pom.xml @@ -66,14 +66,6 @@ true - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - diff --git a/guava-modules/guava-collections-map/pom.xml b/guava-modules/guava-collections-map/pom.xml index 82d634265b..f3f829f25f 100644 --- a/guava-modules/guava-collections-map/pom.xml +++ b/guava-modules/guava-collections-map/pom.xml @@ -38,14 +38,6 @@ true - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - diff --git a/guava-modules/guava-collections-set/pom.xml b/guava-modules/guava-collections-set/pom.xml index 8f58148e41..0e53527aef 100644 --- a/guava-modules/guava-collections-set/pom.xml +++ b/guava-modules/guava-collections-set/pom.xml @@ -37,14 +37,6 @@ guava-collections-set - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - diff --git a/guava-modules/guava-collections/pom.xml b/guava-modules/guava-collections/pom.xml index 53c55dc655..90ed99bab7 100644 --- a/guava-modules/guava-collections/pom.xml +++ b/guava-modules/guava-collections/pom.xml @@ -71,14 +71,6 @@ true - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - diff --git a/guava-modules/guava-io/pom.xml b/guava-modules/guava-io/pom.xml index 6b3280755c..b77bad575d 100644 --- a/guava-modules/guava-io/pom.xml +++ b/guava-modules/guava-io/pom.xml @@ -40,14 +40,6 @@ true - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - \ No newline at end of file diff --git a/guava-modules/guava-utilities/pom.xml b/guava-modules/guava-utilities/pom.xml index 0496f5b2e8..fd9523c224 100644 --- a/guava-modules/guava-utilities/pom.xml +++ b/guava-modules/guava-utilities/pom.xml @@ -52,14 +52,6 @@ true - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - diff --git a/guava-modules/pom.xml b/guava-modules/pom.xml index b625f9fd0f..4b84f616f3 100644 --- a/guava-modules/pom.xml +++ b/guava-modules/pom.xml @@ -46,17 +46,8 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - - + 2.22.2 5.6.2 29.0-jre diff --git a/jackson-modules/pom.xml b/jackson-modules/pom.xml index 70b10e9554..819f11c110 100644 --- a/jackson-modules/pom.xml +++ b/jackson-modules/pom.xml @@ -50,16 +50,6 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - - 5.6.2 diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml index 761dca6afa..8dfd949166 100644 --- a/jackson-simple/pom.xml +++ b/jackson-simple/pom.xml @@ -51,14 +51,6 @@ true - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - diff --git a/java-collections-maps-3/README.md b/java-collections-maps-3/README.md index bd1029c9cf..9b1d8510c2 100644 --- a/java-collections-maps-3/README.md +++ b/java-collections-maps-3/README.md @@ -3,3 +3,4 @@ - [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys) - [Using a Byte Array as Map Key in Java](https://www.baeldung.com/java-map-key-byte-array) - [Using the Map.Entry Java Class](https://www.baeldung.com/java-map-entry) +- [Optimizing HashMap’s Performance](https://www.baeldung.com/java-hashmap-optimize-performance) diff --git a/java-rmi/src/test/java/com/baeldung/rmi/JavaRMIIntegrationTest.java b/java-rmi/src/test/java/com/baeldung/rmi/JavaRMIIntegrationTest.java index 66bfbe49eb..604899de03 100644 --- a/java-rmi/src/test/java/com/baeldung/rmi/JavaRMIIntegrationTest.java +++ b/java-rmi/src/test/java/com/baeldung/rmi/JavaRMIIntegrationTest.java @@ -1,44 +1,42 @@ package com.baeldung.rmi; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.Test; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; public class JavaRMIIntegrationTest { - - @BeforeClass - public static void whenRunServer_thenServerStarts() { - - try { - MessengerServiceImpl server = new MessengerServiceImpl(); - server.createStubAndBind(); - } catch (RemoteException e) { - fail("Exception Occurred"); - } - } - - @Test - public void whenClientSendsMessageToServer_thenServerSendsResponseMessage() { - - try { - Registry registry = LocateRegistry.getRegistry(); - MessengerService server = (MessengerService) registry.lookup("MessengerService"); - String responseMessage = server.sendMessage("Client Message"); - - String expectedMessage = "Server Message"; - assertEquals(responseMessage, expectedMessage); - } catch (RemoteException e) { - fail("Exception Occurred"); - } catch (NotBoundException nb) { - fail("Exception Occurred"); - } - } - + + private MessengerServiceImpl messengerService; + + @Before + public void init() { + try { + messengerService = new MessengerServiceImpl(); + messengerService.createStubAndBind(); + } catch (RemoteException e) { + fail("Exception Occurred: " + e); + } + } + + @Test + public void whenClientSendsMessageToServer_thenServerSendsResponseMessage() { + try { + Registry registry = LocateRegistry.getRegistry(); + MessengerService server = (MessengerService) registry.lookup("MessengerService"); + String responseMessage = server.sendMessage("Client Message"); + + String expectedMessage = "Server Message"; + assertEquals(responseMessage, expectedMessage); + } catch (RemoteException | NotBoundException e) { + fail("Exception Occurred: " + e); + } + } + } \ No newline at end of file diff --git a/jee-7/pom.xml b/jee-7/pom.xml index b0e10c1580..48814e6d2f 100644 --- a/jee-7/pom.xml +++ b/jee-7/pom.xml @@ -523,7 +523,6 @@ 2.25 1.0.0.Final 4.2.3.RELEASE - 2.21.0 1.1.2 2.2.14 4.5 diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointIntegrationTest.java similarity index 96% rename from jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointUnitTest.java rename to jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointIntegrationTest.java index c607efeb24..8190ae5afb 100644 --- a/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointUnitTest.java +++ b/jee-7/src/test/java/com/baeldung/batch/understanding/CustomCheckPointIntegrationTest.java @@ -12,7 +12,7 @@ import javax.batch.runtime.StepExecution; import org.junit.jupiter.api.Test; -class CustomCheckPointUnitTest { +class CustomCheckPointIntegrationTest { @Test public void givenChunk_whenCustomCheckPoint_thenCommitCountIsThree() throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceIntegrationTest.java similarity index 99% rename from jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceUnitTest.java rename to jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceIntegrationTest.java index 4b27e5f5ec..7dda13a752 100644 --- a/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceUnitTest.java +++ b/jee-7/src/test/java/com/baeldung/batch/understanding/JobSequenceIntegrationTest.java @@ -16,7 +16,7 @@ import javax.batch.runtime.StepExecution; import org.junit.jupiter.api.Test; -class JobSequenceUnitTest { +class JobSequenceIntegrationTest { @Test public void givenTwoSteps_thenBatch_CompleteWithSuccess() throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetIntegrationTest.java similarity index 98% rename from jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetUnitTest.java rename to jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetIntegrationTest.java index 788b75eb3e..dc91f747d3 100644 --- a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetUnitTest.java +++ b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleBatchLetIntegrationTest.java @@ -11,7 +11,7 @@ import javax.batch.runtime.JobExecution; import org.junit.jupiter.api.Test; -class SimpleBatchLetUnitTest { +class SimpleBatchLetIntegrationTest { @Test public void givenBatchLet_thenBatch_CompleteWithSuccess() throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkIntegrationTest.java similarity index 99% rename from jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkUnitTest.java rename to jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkIntegrationTest.java index 9010c365a2..a7884dbb32 100644 --- a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkUnitTest.java +++ b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleChunkIntegrationTest.java @@ -16,7 +16,7 @@ import javax.batch.runtime.StepExecution; import org.junit.jupiter.api.Test; -class SimpleChunkUnitTest { +class SimpleChunkIntegrationTest { @Test public void givenChunk_thenBatch_CompletesWithSucess() throws Exception { JobOperator jobOperator = BatchRuntime.getJobOperator(); diff --git a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkUnitTest.java b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkIntegrationTest.java similarity index 97% rename from jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkUnitTest.java rename to jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkIntegrationTest.java index bc410aec8d..8c3beeb2f3 100644 --- a/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkUnitTest.java +++ b/jee-7/src/test/java/com/baeldung/batch/understanding/SimpleErrorChunkIntegrationTest.java @@ -13,7 +13,7 @@ import javax.batch.runtime.StepExecution; import org.junit.jupiter.api.Test; -class SimpleErrorChunkUnitTest { +class SimpleErrorChunkIntegrationTest { @Test public void givenChunkError_thenBatch_CompletesWithFailed() throws Exception { diff --git a/jhipster-5/bookstore-monolith/pom.xml b/jhipster-5/bookstore-monolith/pom.xml index dbc46bbb97..5da3bde449 100644 --- a/jhipster-5/bookstore-monolith/pom.xml +++ b/jhipster-5/bookstore-monolith/pom.xml @@ -1099,8 +1099,6 @@ 2.12.6 v10.15.0 6.4.1 - UTF-8 - UTF-8 ${project.build.directory}/test-results yyyyMMddHHmmss ${java.version} diff --git a/jhipster/jhipster-uaa/gateway/pom.xml b/jhipster/jhipster-uaa/gateway/pom.xml index b417bd7b57..21a04a9692 100644 --- a/jhipster/jhipster-uaa/gateway/pom.xml +++ b/jhipster/jhipster-uaa/gateway/pom.xml @@ -1020,8 +1020,6 @@ 2.12.6 v8.12.0 6.4.1 - UTF-8 - UTF-8 ${project.build.directory}/test-results yyyyMMddHHmmss ${java.version} diff --git a/jhipster/jhipster-uaa/quotes/pom.xml b/jhipster/jhipster-uaa/quotes/pom.xml index f088ad2fd1..12bbf66d37 100644 --- a/jhipster/jhipster-uaa/quotes/pom.xml +++ b/jhipster/jhipster-uaa/quotes/pom.xml @@ -840,8 +840,6 @@ 2.12.6 v8.12.0 6.4.1 - UTF-8 - UTF-8 ${project.build.directory}/test-results yyyyMMddHHmmss ${java.version} diff --git a/jhipster/jhipster-uaa/uaa/pom.xml b/jhipster/jhipster-uaa/uaa/pom.xml index f9c1f226bb..d0d81aa0b3 100644 --- a/jhipster/jhipster-uaa/uaa/pom.xml +++ b/jhipster/jhipster-uaa/uaa/pom.xml @@ -842,8 +842,6 @@ 2.12.6 v8.12.0 6.4.1 - UTF-8 - UTF-8 ${project.build.directory}/test-results yyyyMMddHHmmss ${java.version} diff --git a/jjwt/README.md b/jjwt/README.md index 25f5a8f6f0..1798d5193b 100644 --- a/jjwt/README.md +++ b/jjwt/README.md @@ -47,3 +47,4 @@ Available commands (assumes httpie - https://github.com/jkbrzt/httpie): ## Relevant articles: - [Supercharge Java Authentication with JSON Web Tokens (JWTs)](https://www.baeldung.com/java-json-web-tokens-jjwt) +- [Decode a JWT Token in Java](https://www.baeldung.com/java-jwt-token-decode) diff --git a/jjwt/pom.xml b/jjwt/pom.xml index aa238fafb5..9d38d1b0e9 100644 --- a/jjwt/pom.xml +++ b/jjwt/pom.xml @@ -41,6 +41,12 @@ jjwt ${jjwt.version} + + + org.assertj + assertj-core + test + diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java new file mode 100644 index 0000000000..922d5c0ce5 --- /dev/null +++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtil.java @@ -0,0 +1,46 @@ +package io.jsonwebtoken.jjwtfun.util; + +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator; + +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +import static io.jsonwebtoken.SignatureAlgorithm.HS256; + +public class JWTDecoderUtil { + + public static String decodeJWTToken(String token) { + Base64.Decoder decoder = Base64.getDecoder(); + + String[] chunks = token.split("\\."); + + String header = new String(decoder.decode(chunks[0])); + String payload = new String(decoder.decode(chunks[1])); + + return header + " " + payload; + } + + public static String decodeJWTToken(String token, String secretKey) throws Exception { + Base64.Decoder decoder = Base64.getDecoder(); + + String[] chunks = token.split("\\."); + + String header = new String(decoder.decode(chunks[0])); + String payload = new String(decoder.decode(chunks[1])); + + String tokenWithoutSignature = chunks[0] + "." + chunks[1]; + String signature = chunks[2]; + + SignatureAlgorithm sa = HS256; + SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), sa.getJcaName()); + + DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec); + + if (!validator.isValid(tokenWithoutSignature, signature)) { + throw new Exception("Could not verify JWT token integrity!"); + } + + return header + " " + payload; + } +} diff --git a/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java new file mode 100644 index 0000000000..3103a6c8a3 --- /dev/null +++ b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/util/JWTDecoderUtilUnitTest.java @@ -0,0 +1,32 @@ +package io.jsonwebtoken.jjwtfun.util; + +import io.jsonwebtoken.SignatureAlgorithm; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class JWTDecoderUtilUnitTest { + + private final static String SIMPLE_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9"; + private final static String SIGNED_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE"; + + @Test + void givenSimpleToken_whenDecoding_thenStringOfHeaderPayloadAreReturned() { + assertThat(JWTDecoderUtil.decodeJWTToken(SIMPLE_TOKEN)) + .contains(SignatureAlgorithm.HS256.getValue()); + } + + @Test + void givenSignedToken_whenDecodingWithInvalidSecret_thenIntegrityIsNotValidated() { + assertThatThrownBy(() -> JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "BAD_SECRET")) + .hasMessage("Could not verify JWT token integrity!"); + } + + @Test + void givenSignedToken_whenDecodingWithValidSecret_thenIntegrityIsValidated() throws Exception { + assertThat(JWTDecoderUtil.decodeJWTToken(SIGNED_TOKEN, "MySecretKey")) + .contains("Baeldung User"); + } +} diff --git a/jmeter/README.md b/jmeter/README.md index 11351ffdda..53aca8d34b 100644 --- a/jmeter/README.md +++ b/jmeter/README.md @@ -52,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-write-to-file) diff --git a/jmh/pom.xml b/jmh/pom.xml index 16a5bc54a4..ecee66f410 100644 --- a/jmh/pom.xml +++ b/jmh/pom.xml @@ -19,12 +19,12 @@ org.openjdk.jmh jmh-core - ${openjdk.jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${openjdk.jmh.version} + ${jmh-generator.version} org.openjdk.jol @@ -76,7 +76,6 @@ - 1.19 3.0.2 0.10 3.2.0 diff --git a/kubernetes/k8s-intro/README.md b/kubernetes/k8s-intro/README.md new file mode 100644 index 0000000000..0055e8a27c --- /dev/null +++ b/kubernetes/k8s-intro/README.md @@ -0,0 +1,17 @@ +# Kubernetes Java API Sample Code + +This module contains sample code used to show how to use the Kubernetes client Java API. + +Before running those samples, make sure that your environment is correctly configured to access +a working Kubernetes cluster. + +An easy way to check that everything is working as expected is issuing any *kubectl get* command: + +```shell +$ kubectl get nodes +``` +If you get a valid response, then you're good to go. + +### Relevant Articles: + +- [Paging and Async Calls with the Kubernetes API](https://www.baeldung.com/java-kubernetes-paging-async) diff --git a/kubernetes/k8s-intro/pom.xml b/kubernetes/k8s-intro/pom.xml new file mode 100644 index 0000000000..4a5bb09711 --- /dev/null +++ b/kubernetes/k8s-intro/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + + com.baeldung + kubernetes-parent + 1.0.0-SNAPSHOT + + k8s-intro + 0.0.1-SNAPSHOT + + + + io.kubernetes + client-java + 11.0.0 + + + + ch.qos.logback + logback-classic + 1.2.3 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ApiInvoker.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ApiInvoker.java new file mode 100644 index 0000000000..fbc2662170 --- /dev/null +++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ApiInvoker.java @@ -0,0 +1,11 @@ +package com.baeldung.kubernetes.intro; + +import io.kubernetes.client.openapi.ApiCallback; +import io.kubernetes.client.openapi.ApiException; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import okhttp3.Call; + +@FunctionalInterface +public interface ApiInvoker { + Call apply(CoreV1Api api, ApiCallback callback) throws ApiException; +} diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/AsyncHelper.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/AsyncHelper.java new file mode 100644 index 0000000000..d9c29dcb64 --- /dev/null +++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/AsyncHelper.java @@ -0,0 +1,74 @@ +package com.baeldung.kubernetes.intro; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import java.util.function.BiFunction; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.kubernetes.client.openapi.ApiCallback; +import io.kubernetes.client.openapi.ApiException; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import okhttp3.Call; + +public class AsyncHelper implements ApiCallback { + + private static final Logger log = LoggerFactory.getLogger(AsyncHelper.class); + + private CoreV1Api api; + private CompletableFuture callResult; + + private AsyncHelper(CoreV1Api api) { + this.api = api; + } + + public static CompletableFuture doAsync(CoreV1Api api, ApiInvoker invoker) { + + AsyncHelper p = new AsyncHelper<>(api); + return p.execute(invoker); + } + + private CompletableFuture execute( ApiInvoker invoker) { + + try { + callResult = new CompletableFuture<>(); + log.info("[I38] Calling API..."); + final Call call = invoker.apply(api,this); + log.info("[I41] API Succesfully invoked: method={}, url={}", + call.request().method(), + call.request().url()); + return callResult; + } + catch(ApiException aex) { + callResult.completeExceptionally(aex); + return callResult; + } + } + + @Override + public void onFailure(ApiException e, int statusCode, Map> responseHeaders) { + log.error("[E53] onFailure",e); + callResult.completeExceptionally(e); + } + + @Override + public void onSuccess(R result, int statusCode, Map> responseHeaders) { + log.error("[E61] onSuccess: statusCode={}",statusCode); + callResult.complete(result); + } + + @Override + public void onUploadProgress(long bytesWritten, long contentLength, boolean done) { + log.info("[E61] onUploadProgress: bytesWritten={}, contentLength={}, done={}",bytesWritten,contentLength,done); + } + + @Override + public void onDownloadProgress(long bytesRead, long contentLength, boolean done) { + log.info("[E75] onDownloadProgress: bytesRead={}, contentLength={}, done={}",bytesRead,contentLength,done); + } +} + diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodes.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodes.java new file mode 100644 index 0000000000..b0e540eb3a --- /dev/null +++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodes.java @@ -0,0 +1,31 @@ +/** + * + */ +package com.baeldung.kubernetes.intro; + + +import io.kubernetes.client.openapi.ApiClient; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.models.V1NodeList; +import io.kubernetes.client.util.Config; + +/** + * @author Philippe + * + */ +public class ListNodes { + + /** + * @param args + */ + public static void main(String[] args) throws Exception { + + ApiClient client = Config.defaultClient(); + CoreV1Api api = new CoreV1Api(client); + V1NodeList nodeList = api.listNode(null, null, null, null, null, null, null, null, 10, false); + nodeList.getItems() + .stream() + .forEach((node) -> System.out.println(node.getMetadata())); + } + +} diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodesAsync.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodesAsync.java new file mode 100644 index 0000000000..acd4512196 --- /dev/null +++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListNodesAsync.java @@ -0,0 +1,50 @@ +/** + * + */ +package com.baeldung.kubernetes.intro; + + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.kubernetes.client.openapi.ApiClient; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.models.V1NodeList; +import io.kubernetes.client.util.Config; + +/** + * @author Philippe + * + */ +public class ListNodesAsync { + + private static Logger log = LoggerFactory.getLogger(ListNodesAsync.class); + /** + * @param args + */ + public static void main(String[] args) throws Exception { + + // Initial setup + ApiClient client = Config.defaultClient(); + CoreV1Api api = new CoreV1Api(client); + + // Start async call + CompletableFuture p = AsyncHelper.doAsync(api,(capi,cb) -> + capi.listNodeAsync(null, null, null, null, null, null, null, null, 10, false, cb) + ); + + p.thenAcceptAsync((nodeList) -> { + log.info("[I40] Processing results..."); + nodeList.getItems() + .stream() + .forEach((node) -> System.out.println(node.getMetadata())); + }); + + log.info("[I46] Waiting results..."); + p.get(10, TimeUnit.SECONDS); + } + +} diff --git a/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListPodsPaged.java b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListPodsPaged.java new file mode 100644 index 0000000000..1c160ae607 --- /dev/null +++ b/kubernetes/k8s-intro/src/main/java/com/baeldung/kubernetes/intro/ListPodsPaged.java @@ -0,0 +1,46 @@ +/** + * + */ +package com.baeldung.kubernetes.intro; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.kubernetes.client.openapi.ApiClient; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.models.V1NodeList; +import io.kubernetes.client.openapi.models.V1PodList; +import io.kubernetes.client.util.Config; + +/** + * @author Philippe + * + */ +public class ListPodsPaged { + + private static final Logger log = LoggerFactory.getLogger(ListPodsPaged.class); + + /** + * @param args + */ + public static void main(String[] args) throws Exception { + + ApiClient client = Config.defaultClient(); + CoreV1Api api = new CoreV1Api(client); + String continuationToken = null; + int limit = 2; // Just for illustration purposes. Real world values would range from ~100 to ~1000/page + Long remaining = null; + do { + log.info("=========================================================================="); + log.info("Retrieving data: continuationToken={}, remaining={}", continuationToken,remaining); + V1PodList items = api.listPodForAllNamespaces(null, continuationToken, null, null, limit, null, null, null, 10, false); + continuationToken = items.getMetadata().getContinue(); + remaining = items.getMetadata().getRemainingItemCount(); + items.getItems() + .stream() + .forEach((node) -> System.out.println(node.getMetadata())); + } while( continuationToken != null ); + } + +} diff --git a/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesAsyncLiveTest.java b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesAsyncLiveTest.java new file mode 100644 index 0000000000..af32df8224 --- /dev/null +++ b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesAsyncLiveTest.java @@ -0,0 +1,10 @@ +package com.baeldung.kubernetes.intro; + +import org.junit.jupiter.api.Test; + +class ListNodesAsyncLiveTest { + @Test + void whenListNodes_thenSuccess() throws Exception { + ListNodesAsync.main(new String[] {}); + } +} diff --git a/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesLiveTest.java b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesLiveTest.java new file mode 100644 index 0000000000..84a3efb903 --- /dev/null +++ b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListNodesLiveTest.java @@ -0,0 +1,10 @@ +package com.baeldung.kubernetes.intro; + +import org.junit.jupiter.api.Test; + +class ListNodesLiveTest { + @Test + void whenListNodes_thenSuccess() throws Exception { + ListNodes.main(new String[] {}); + } +} diff --git a/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListPodsPagedLiveTest.java b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListPodsPagedLiveTest.java new file mode 100644 index 0000000000..6fb3c5b32d --- /dev/null +++ b/kubernetes/k8s-intro/src/test/java/com/baeldung/kubernetes/intro/ListPodsPagedLiveTest.java @@ -0,0 +1,10 @@ +package com.baeldung.kubernetes.intro; + +import org.junit.jupiter.api.Test; + +class ListPodsPagedLiveTest { + @Test + void whenListPodsPage_thenSuccess() throws Exception { + ListPodsPaged.main(new String[] {}); + } +} diff --git a/kubernetes/k8s-intro/src/test/resources/logback.xml b/kubernetes/k8s-intro/src/test/resources/logback.xml new file mode 100644 index 0000000000..479545e643 --- /dev/null +++ b/kubernetes/k8s-intro/src/test/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + diff --git a/kubernetes/pom.xml b/kubernetes/pom.xml new file mode 100644 index 0000000000..fe10295e44 --- /dev/null +++ b/kubernetes/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + kubernetes-parent + pom + + k8s-intro + + \ No newline at end of file diff --git a/libraries-5/pom.xml b/libraries-5/pom.xml index 63347dd60d..c0de1af822 100644 --- a/libraries-5/pom.xml +++ b/libraries-5/pom.xml @@ -55,12 +55,12 @@ net.bytebuddy byte-buddy - ${bytebuddy.version} + ${byte-buddy.version} net.bytebuddy byte-buddy-agent - ${bytebuddy.version} + ${byte-buddy.version} @@ -115,7 +115,7 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} @@ -127,14 +127,12 @@ 2.11 2.5.11 0.6.5 - 1.7.1 3.0.14 2.5.5 3.0.2 4.5.1 1.0 2.1.2 - 1.19 \ No newline at end of file diff --git a/libraries-http-2/README.md b/libraries-http-2/README.md index c0d6e76f1b..f3fdf1becb 100644 --- a/libraries-http-2/README.md +++ b/libraries-http-2/README.md @@ -7,5 +7,6 @@ This module contains articles about HTTP libraries. - [Jetty ReactiveStreams HTTP Client](https://www.baeldung.com/jetty-reactivestreams-http-client) - [Decode an OkHttp JSON Response](https://www.baeldung.com/okhttp-json-response) - [Retrofit 2 – Dynamic URL](https://www.baeldung.com/retrofit-dynamic-url) +- [Adding Interceptors in OkHTTP](https://www.baeldung.com/java-okhttp-interceptors) - More articles [[<-- prev]](/libraries-http) diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index d0bdb26bd4..855008521f 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 libraries-http-2 libraries-http-2 @@ -13,12 +13,17 @@ - + com.squareup.okhttp3 okhttp ${okhttp.version} + + com.squareup.okhttp3 + logging-interceptor + ${okhttp.version} + com.fasterxml.jackson.core jackson-databind @@ -81,9 +86,9 @@ - 3.14.2 + 4.9.1 2.8.5 - 3.14.2 + 4.9.1 1.0.3 9.4.19.v20190610 2.2.11 diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/CacheControlResponeInterceptor.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/CacheControlResponeInterceptor.java new file mode 100644 index 0000000000..e9f8db19be --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/CacheControlResponeInterceptor.java @@ -0,0 +1,18 @@ +package com.baeldung.okhttp.interceptors; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Response; + +public class CacheControlResponeInterceptor implements Interceptor { + + @Override + public Response intercept(Chain chain) throws IOException { + Response response = chain.proceed(chain.request()); + return response.newBuilder() + .header("Cache-Control", "no-store") + .build(); + } + +} diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/ErrorMessage.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/ErrorMessage.java new file mode 100644 index 0000000000..73411d947f --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/ErrorMessage.java @@ -0,0 +1,21 @@ +package com.baeldung.okhttp.interceptors; + +public class ErrorMessage { + + private final int status; + private final String detail; + + public ErrorMessage(int status, String detail) { + this.status = status; + this.detail = detail; + } + + public int getStatus() { + return status; + } + + public String getDetail() { + return detail; + } + +} diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/ErrorResponseInterceptor.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/ErrorResponseInterceptor.java new file mode 100644 index 0000000000..f6c6673705 --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/ErrorResponseInterceptor.java @@ -0,0 +1,32 @@ +package com.baeldung.okhttp.interceptors; + +import java.io.IOException; + +import com.google.gson.Gson; + +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Response; +import okhttp3.ResponseBody; + +public class ErrorResponseInterceptor implements Interceptor { + + public static final MediaType APPLICATION_JSON = MediaType.get("application/json; charset=utf-8"); + + @Override + public Response intercept(Chain chain) throws IOException { + Response response = chain.proceed(chain.request()); + + if(!response.isSuccessful()) { + Gson gson = new Gson(); + String body = gson.toJson(new ErrorMessage(response.code(), "The response from the server was not OK")); + ResponseBody responseBody = ResponseBody.create(body, APPLICATION_JSON); + + return response.newBuilder() + .body(responseBody) + .build(); + } + return response; + } + +} diff --git a/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/SimpleLoggingInterceptor.java b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/SimpleLoggingInterceptor.java new file mode 100644 index 0000000000..6d08546eea --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/okhttp/interceptors/SimpleLoggingInterceptor.java @@ -0,0 +1,25 @@ +package com.baeldung.okhttp.interceptors; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +public class SimpleLoggingInterceptor implements Interceptor { + + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleLoggingInterceptor.class); + + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + + LOGGER.info("Intercepted headers: {} from URL: {}", request.headers(), request.url()); + + return chain.proceed(request); + } + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/okhttp/interceptors/InterceptorIntegrationTest.java b/libraries-http-2/src/test/java/com/baeldung/okhttp/interceptors/InterceptorIntegrationTest.java new file mode 100644 index 0000000000..d15b67ad3b --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/okhttp/interceptors/InterceptorIntegrationTest.java @@ -0,0 +1,90 @@ +package com.baeldung.okhttp.interceptors; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Rule; +import org.junit.Test; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.logging.HttpLoggingInterceptor; +import okhttp3.logging.HttpLoggingInterceptor.Level; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +public class InterceptorIntegrationTest { + + @Rule + public MockWebServer server = new MockWebServer(); + + @Test + public void givenSimpleLogginInterceptor_whenRequestSent_thenHeadersLogged() throws IOException { + server.enqueue(new MockResponse().setBody("Hello Baeldung Readers!")); + + OkHttpClient client = new OkHttpClient.Builder() + .addNetworkInterceptor(new SimpleLoggingInterceptor()) + .build(); + + Request request = new Request.Builder() + .url(server.url("/greeting")) + .header("User-Agent", "A Baeldung Reader") + .build(); + + try (Response response = client.newCall(request).execute()) { + assertEquals("Response code should be: ", 200, response.code()); + assertEquals("Body should be: ", "Hello Baeldung Readers!", response.body().string()); + } + } + + @Test + public void givenResponseInterceptor_whenRequestSent_thenCacheControlSetToNoStore() throws IOException { + server.enqueue(new MockResponse().setBody("Hello Baeldung Readers!")); + + OkHttpClient client = new OkHttpClient.Builder() + .addInterceptor(getHttpLogger()) + .addInterceptor(new CacheControlResponeInterceptor()) + .build(); + + Request request = new Request.Builder() + .url(server.url("/greeting")) + .header("User-Agent", "A Baeldung Reader") + .build(); + + try (Response response = client.newCall(request).execute()) { + assertEquals("Response code should be: ", 200, response.code()); + assertEquals("Body should be: ", "Hello Baeldung Readers!", response.body().string()); + assertEquals("Response cache-control should be", "no-store", response.header("Cache-Control")); + } + } + + @Test + public void givenErrorResponseInterceptor_whenResponseIs500_thenBodyIsJsonWithStatus() throws IOException { + server.enqueue(new MockResponse().setResponseCode(500).setBody("Hello Baeldung Readers!")); + + OkHttpClient client = new OkHttpClient.Builder() + .addInterceptor(getHttpLogger()) + .addInterceptor(new ErrorResponseInterceptor()) + .build(); + + Request request = new Request.Builder() + .url(server.url("/greeting")) + .header("User-Agent", "A Baeldung Reader") + .build(); + + try (Response response = client.newCall(request).execute()) { + assertEquals("Response code should be: ", 500, response.code()); + assertEquals("Body should be: ", "{\"status\":500,\"detail\":\"The response from the server was not OK\"}", + response.body().string()); + } + } + + private HttpLoggingInterceptor getHttpLogger() { + HttpLoggingInterceptor logger = new HttpLoggingInterceptor(); + logger.setLevel(Level.HEADERS); + return logger; + } + +} diff --git a/libraries-primitive/pom.xml b/libraries-primitive/pom.xml index 1370468e76..a3bf5e0d9d 100644 --- a/libraries-primitive/pom.xml +++ b/libraries-primitive/pom.xml @@ -26,13 +26,13 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} test org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} test @@ -46,10 +46,11 @@ 8.2.2 4.12 - 1.19 10.0.0 1.8 1.8 + 1.28 + 1.28 \ No newline at end of file diff --git a/libraries/pom.xml b/libraries/pom.xml index fee66f928d..5924ed009a 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -202,7 +202,7 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} junit @@ -395,7 +395,6 @@ 3.0.3 2.3.0 0.9.12 - 1.19 3.0.2 3.6 2.6 diff --git a/logging-modules/log-mdc/pom.xml b/logging-modules/log-mdc/pom.xml index 5e2155fde9..a7cfd3faa8 100644 --- a/logging-modules/log-mdc/pom.xml +++ b/logging-modules/log-mdc/pom.xml @@ -95,14 +95,6 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - diff --git a/logging-modules/pom.xml b/logging-modules/pom.xml index b5354c7c23..85d5c18219 100644 --- a/logging-modules/pom.xml +++ b/logging-modules/pom.xml @@ -21,16 +21,6 @@ flogger - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - - 5.6.2 diff --git a/maven-modules/maven-plugins/jaxws/README.md b/maven-modules/maven-plugins/jaxws/README.md new file mode 100644 index 0000000000..d17df7a5f6 --- /dev/null +++ b/maven-modules/maven-plugins/jaxws/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Generate WSDL Stubs with Maven](https://www.baeldung.com/maven-wsdl-stubs) diff --git a/maven-modules/maven-plugins/jaxws/pom.xml b/maven-modules/maven-plugins/jaxws/pom.xml new file mode 100644 index 0000000000..161c1dc731 --- /dev/null +++ b/maven-modules/maven-plugins/jaxws/pom.xml @@ -0,0 +1,45 @@ + + + + maven-plugins + com.baeldung + 0.0.1-SNAPSHOT + + 4.0.0 + + jaxws + + + + org.codehaus.mojo + jaxws-maven-plugin + 2.6 + + + + wsimport + + + + + ${project.basedir}/src/main/resources/ + com.baeldung.soap.ws.client + + ${project.build.directory}/generated-sources/ + + + + + maven-verifier-plugin + ${maven.verifier.version} + + ../input-resources/verifications.xml + false + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-plugins/jaxws/src/main/java/com/baeldung/soap/ws/client/CountryNotFoundException.java b/maven-modules/maven-plugins/jaxws/src/main/java/com/baeldung/soap/ws/client/CountryNotFoundException.java new file mode 100644 index 0000000000..c68d65abb1 --- /dev/null +++ b/maven-modules/maven-plugins/jaxws/src/main/java/com/baeldung/soap/ws/client/CountryNotFoundException.java @@ -0,0 +1,8 @@ +package com.baeldung.soap.ws.client; + +public class CountryNotFoundException extends RuntimeException { + + public CountryNotFoundException() { + super("Country not found!"); + } +} diff --git a/maven-modules/maven-plugins/jaxws/src/main/java/com/baeldung/soap/ws/client/CountryServiceClient.java b/maven-modules/maven-plugins/jaxws/src/main/java/com/baeldung/soap/ws/client/CountryServiceClient.java new file mode 100644 index 0000000000..d6175890f9 --- /dev/null +++ b/maven-modules/maven-plugins/jaxws/src/main/java/com/baeldung/soap/ws/client/CountryServiceClient.java @@ -0,0 +1,27 @@ +package com.baeldung.soap.ws.client; + +import java.util.Optional; + +public class CountryServiceClient { + + private CountryService countryService; + + public CountryServiceClient(CountryService countryService) { + this.countryService = countryService; + } + + public String getCapitalByCountryName(String countryName) { + return Optional.of(countryService.findByName(countryName)) + .map(Country::getCapital).orElseThrow(CountryNotFoundException::new); + } + + public int getPopulationByCountryName(String countryName) { + return Optional.of(countryService.findByName(countryName)) + .map(Country::getPopulation).orElseThrow(CountryNotFoundException::new); + } + + public Currency getCurrencyByCountryName(String countryName) { + return Optional.of(countryService.findByName(countryName)) + .map(Country::getCurrency).orElseThrow(CountryNotFoundException::new); + } +} diff --git a/maven-modules/maven-plugins/jaxws/src/main/resources/country.wsdl b/maven-modules/maven-plugins/jaxws/src/main/resources/country.wsdl new file mode 100644 index 0000000000..b6efb7087f --- /dev/null +++ b/maven-modules/maven-plugins/jaxws/src/main/resources/country.wsdl @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-plugins/jaxws/src/main/resources/country.xsd b/maven-modules/maven-plugins/jaxws/src/main/resources/country.xsd new file mode 100644 index 0000000000..c94b6047f9 --- /dev/null +++ b/maven-modules/maven-plugins/jaxws/src/main/resources/country.xsd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-plugins/jaxws/src/test/java/com/baeldung/soap/ws/client/CountryServiceClientUnitTest.java b/maven-modules/maven-plugins/jaxws/src/test/java/com/baeldung/soap/ws/client/CountryServiceClientUnitTest.java new file mode 100644 index 0000000000..65c4f39ee4 --- /dev/null +++ b/maven-modules/maven-plugins/jaxws/src/test/java/com/baeldung/soap/ws/client/CountryServiceClientUnitTest.java @@ -0,0 +1,73 @@ +package com.baeldung.soap.ws.client; + +import org.junit.jupiter.api.*; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +class CountryServiceClientUnitTest { + + CountryServiceClient countryServiceClient; + CountryService countryService; + + @BeforeEach + void setUp() { + countryService = mock(CountryService.class); + countryServiceClient = new CountryServiceClient(countryService); + } + + @DisplayName("Get capital by country name when country not found") + @Test + void givenCountryDoesNotExist_whenGetCapitalByCountryName_thenThrowsCountryNotFoundException() { + doThrow(CountryNotFoundException.class).when(countryService).findByName(any()); + Assertions.assertThrows(CountryNotFoundException.class, () -> countryServiceClient.getCapitalByCountryName(any())); + } + + @DisplayName("Get capital by country name when country is India then should return capital") + @Test + void givenCountryIndia_whenGetCapitalByCountryName_thenShouldReturnCapital() { + Country country = mock(Country.class); + + doReturn("New Delhi").when(country).getCapital(); + doReturn(country).when(countryService).findByName("India"); + + Assertions.assertEquals("New Delhi", countryServiceClient.getCapitalByCountryName("India")); + } + + @DisplayName("Get population by country name when country not found") + @Test + void givenCountryDoesNotExist_getPopulationByCountryName_thenThrowsCountryNotFoundException() { + doThrow(CountryNotFoundException.class).when(countryService).findByName(any()); + Assertions.assertThrows(CountryNotFoundException.class, () -> countryServiceClient.getPopulationByCountryName(any())); + } + + @DisplayName("Get population by country name when country is India then should return population") + @Test + void givenCountryIndia_getPopulationByCountryName_thenShouldReturnPopulation() { + Country country = mock(Country.class); + + doReturn(1000000).when(country).getPopulation(); + doReturn(country).when(countryService).findByName("India"); + + Assertions.assertEquals(1000000, countryServiceClient.getPopulationByCountryName("India")); + } + + @DisplayName("Get currency by country name when country not found") + @Test + void givenCountryDoesNotExist_getCurrencyByCountryName_thenThrowsCountryNotFoundException() { + doThrow(CountryNotFoundException.class).when(countryService).findByName(any()); + Assertions.assertThrows(CountryNotFoundException.class, () -> countryServiceClient.getCurrencyByCountryName(any())); + } + + @DisplayName("Get currency by country name when country is India then should return currency") + @Test + void givenCountryIndia_getCurrencyByCountryName_thenShouldReturnCurrency() { + Country country = mock(Country.class); + + doReturn(Currency.INR).when(country).getCurrency(); + doReturn(country).when(countryService).findByName("India"); + + Assertions.assertEquals(Currency.INR, countryServiceClient.getCurrencyByCountryName("India")); + } + +} \ No newline at end of file diff --git a/maven-modules/maven-plugins/pom.xml b/maven-modules/maven-plugins/pom.xml index 9f28871ec0..20bdb4b45a 100644 --- a/maven-modules/maven-plugins/pom.xml +++ b/maven-modules/maven-plugins/pom.xml @@ -17,6 +17,7 @@ custom-rule maven-enforcer + jaxws diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index ace3e538c9..f5bf8784a9 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -82,7 +82,7 @@ 3.3.0 1.0.22.RELEASE - 2.4.0 + 2.4.3 1.9.1 3.4.0 diff --git a/parent-java/pom.xml b/parent-java/pom.xml index 9170f45bbe..ce79b34f57 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -32,18 +32,17 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} 29.0-jre - 1.19 2.3.7 2.2 diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index 5893701c68..3219c504d5 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -31,7 +31,7 @@ - 5.2.8.RELEASE + 5.3.3 5.2.3.RELEASE 1.5.10.RELEASE diff --git a/patterns/clean-architecture/pom.xml b/patterns/clean-architecture/pom.xml index 6e7de78751..b9968095f8 100644 --- a/patterns/clean-architecture/pom.xml +++ b/patterns/clean-architecture/pom.xml @@ -15,10 +15,6 @@ ../../parent-boot-2 - - 1.8 - - com.h2database diff --git a/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java b/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java index 099864589c..03bed5fedf 100644 --- a/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java +++ b/patterns/design-patterns-behavioral/src/main/java/com/baeldung/nulls/UsingOptional.java @@ -38,8 +38,8 @@ public class UsingOptional { .flatMap(list -> list.stream().findFirst()); } - private Optional getOptionalList() { - return Optional.ofNullable(getList()); + private Optional> getOptionalList() { + return Optional.of(getList()); } private String doSomething(boolean processed) { diff --git a/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java b/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java index 73797d48c8..576d2bacf3 100644 --- a/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java +++ b/patterns/design-patterns-behavioral/src/test/java/com/baeldung/nulls/UsingOptionalUnitTest.java @@ -19,22 +19,22 @@ class UsingOptionalUnitTest { } @Test - public void whenArgIsFalse_thenReturnEmptyResponse() { + void whenArgIsFalse_thenReturnEmptyResponse() { Optional result = dataObject.process(false); assertFalse(result.isPresent()); } @Test - public void whenArgIsTrue_thenReturnValidResponse() { + void whenArgIsTrue_thenReturnValidResponse() { Optional result = dataObject.process(true); assertTrue(result.isPresent()); } @Test - public void whenArgIsFalse_thenChainResponseAndThrowException() { - assertThrows(Exception.class, () -> dataObject.process(false).orElseThrow(() -> new Exception())); + void whenArgIsFalse_thenChainResponseAndThrowException() { + assertThrows(Exception.class, () -> dataObject.process(false).orElseThrow(Exception::new)); } @Test() @@ -51,7 +51,4 @@ class UsingOptionalUnitTest { void whenOptionalListFirst_returnsEmptyOptional() { assertFalse(dataObject.optionalListFirst().isPresent()); } - - - } \ No newline at end of file diff --git a/patterns/hexagonal-architecture/pom.xml b/patterns/hexagonal-architecture/pom.xml index 62f55c2efa..db7ee69e2e 100644 --- a/patterns/hexagonal-architecture/pom.xml +++ b/patterns/hexagonal-architecture/pom.xml @@ -15,10 +15,6 @@ ../../parent-boot-2 - - 1.8 - - org.springframework.boot diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index fb3f82df38..c203f0a923 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -42,12 +42,12 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} provided @@ -67,7 +67,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} org.mapstruct @@ -147,19 +147,11 @@ maven-source-plugin ${source.plugin.version} - - maven-surefire-plugin - ${surefire.plugin.version} - - - 1.23 1.5.4 6.5.0 1.3.1.Final @@ -185,7 +177,6 @@ 3.1.0 3.9.1 3.2.1 - 2.17 diff --git a/persistence-modules/apache-bookkeeper/pom.xml b/persistence-modules/apache-bookkeeper/pom.xml index 32467b9997..3ef1f50d63 100644 --- a/persistence-modules/apache-bookkeeper/pom.xml +++ b/persistence-modules/apache-bookkeeper/pom.xml @@ -31,7 +31,7 @@ org.testcontainers testcontainers - 1.14.3 + ${testcontainers.version} test @@ -39,6 +39,7 @@ 4.10.0 + 1.14.3 diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/tableexists/DatabaseConfig.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/tableexists/DatabaseConfig.java new file mode 100644 index 0000000000..4ea8a5203e --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/tableexists/DatabaseConfig.java @@ -0,0 +1,21 @@ +package com.baeldung.tableexists; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +class DatabaseConfig { + static Connection connect() throws ClassNotFoundException, SQLException { + Class.forName("org.h2.Driver"); + String url = "jdbc:h2:mem:testdb"; + return DriverManager.getConnection(url, "user", "password"); + } + + static void createTables(Connection connection) throws SQLException { + connection.createStatement().executeUpdate("create table EMPLOYEE (id int primary key auto_increment, name VARCHAR(255))"); + } + + static void dropTables(Connection connection) throws SQLException { + connection.createStatement().executeUpdate("drop table EMPLOYEE"); + } +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/tableexists/TableChecker.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/tableexists/TableChecker.java new file mode 100644 index 0000000000..e6b2ea2fcf --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/tableexists/TableChecker.java @@ -0,0 +1,35 @@ +package com.baeldung.tableexists; + +import java.sql.*; + +class TableChecker { + static void printAllTables(Connection connection, String tableName) throws SQLException { + DatabaseMetaData databaseMetaData = connection.getMetaData(); + ResultSet resultSet = databaseMetaData.getTables(null, null, tableName, new String[] {"TABLE"}); + + while (resultSet.next()) { + String name = resultSet.getString("TABLE_NAME"); + String schema = resultSet.getString("TABLE_SCHEM"); + System.out.println(name + " on schema " + schema); + } + } + + static boolean tableExists(Connection connection, String tableName) throws SQLException { + DatabaseMetaData meta = connection.getMetaData(); + ResultSet resultSet = meta.getTables(null, null, tableName, new String[] {"TABLE"}); + + return resultSet.next(); + } + + static boolean tableExistsSQL(Connection connection, String tableName) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement("SELECT count(*) " + + "FROM information_schema.tables " + + "WHERE table_name = ?" + + "LIMIT 1;"); + preparedStatement.setString(1, tableName); + + ResultSet resultSet = preparedStatement.executeQuery(); + resultSet.next(); + return resultSet.getInt(1) != 0; + } +} diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/tableexists/TableCheckerTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/tableexists/TableCheckerTest.java new file mode 100644 index 0000000000..d7322332a5 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/tableexists/TableCheckerTest.java @@ -0,0 +1,70 @@ +package com.baeldung.tableexists; + +import org.junit.jupiter.api.Test; + +import java.sql.Connection; +import java.sql.SQLException; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TableCheckerUnitTest { + + @Test + void givenCreatedTable_shouldFindTable() throws SQLException, ClassNotFoundException { + // given + Connection connection = DatabaseConfig.connect(); + DatabaseConfig.createTables(connection); + + // when + boolean tableExists = TableChecker.tableExists(connection, "EMPLOYEE"); + + // then + TableChecker.printAllTables(connection, null); + assertTrue(tableExists); + + DatabaseConfig.dropTables(connection); + } + + @Test + void givenCreatedTable_shouldFindTableWithSQL() throws SQLException, ClassNotFoundException { + // given + Connection connection = DatabaseConfig.connect(); + DatabaseConfig.createTables(connection); + + // when + boolean tableExists = TableChecker.tableExistsSQL(connection, "EMPLOYEE"); + + // then + TableChecker.printAllTables(connection, null); + assertTrue(tableExists); + + DatabaseConfig.dropTables(connection); + } + + @Test + void givenNoTable_shouldNotFindTable() throws SQLException, ClassNotFoundException { + // given + Connection connection = DatabaseConfig.connect(); + + // when + boolean tableExists = TableChecker.tableExists(connection, "EMPLOYEE"); + + // then + TableChecker.printAllTables(connection, null); + assertFalse(tableExists); + } + + @Test + void givenNoTable_shouldNotFindTableWithSQL() throws SQLException, ClassNotFoundException { + // given + Connection connection = DatabaseConfig.connect(); + + // when + boolean tableExists = TableChecker.tableExistsSQL(connection, "EMPLOYEE"); + + // then + TableChecker.printAllTables(connection, null); + assertFalse(tableExists); + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-jpa/pom.xml b/persistence-modules/hibernate-jpa/pom.xml index 07b1ee1c51..e5056c413b 100644 --- a/persistence-modules/hibernate-jpa/pom.xml +++ b/persistence-modules/hibernate-jpa/pom.xml @@ -79,7 +79,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${openjdk-jmh.version} + ${jmh-generator.version} org.postgresql @@ -94,7 +94,6 @@ 42.2.11 2.2.3 3.8.0 - 1.21 2.1.7.RELEASE diff --git a/persistence-modules/hibernate-libraries/pom.xml b/persistence-modules/hibernate-libraries/pom.xml index f67309cf43..053ad05167 100644 --- a/persistence-modules/hibernate-libraries/pom.xml +++ b/persistence-modules/hibernate-libraries/pom.xml @@ -175,7 +175,6 @@ 2.0.0 1.2.3 3.0.2 - 2.22.2 3.8.1 3.8.1 8.0.19 diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml index 4374c833c2..d44bc0f8ae 100644 --- a/persistence-modules/hibernate-queries/pom.xml +++ b/persistence-modules/hibernate-queries/pom.xml @@ -53,7 +53,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${openjdk-jmh.version} + ${jmh-generator.version} @@ -61,7 +61,6 @@ 6.0.6 2.2.3 3.8.0 - 1.21 diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml index 3feffc98fd..fe0e7680ab 100644 --- a/persistence-modules/hibernate5/pom.xml +++ b/persistence-modules/hibernate5/pom.xml @@ -59,7 +59,7 @@ org.openjdk.jmh jmh-generator-annprocess - ${openjdk-jmh.version} + ${jmh-generator.version} @@ -68,7 +68,6 @@ 6.0.6 2.2.3 3.8.0 - 1.21 diff --git a/persistence-modules/java-jpa-3/pom.xml b/persistence-modules/java-jpa-3/pom.xml index 7c02cc6c8e..f931cd90b8 100644 --- a/persistence-modules/java-jpa-3/pom.xml +++ b/persistence-modules/java-jpa-3/pom.xml @@ -30,17 +30,17 @@ mysql mysql-connector-java - 8.0.21 + ${mysql.version} com.fasterxml.jackson.core jackson-databind - 2.11.3 + ${jackson.version} com.fasterxml.jackson.datatype jackson-datatype-hibernate5 - 2.9.8 + ${jackson.version} @@ -87,6 +87,7 @@ 5.4.14.Final 2.7.4 42.2.5 + 8.0.21 2.2 3.11.1 3.5.1 diff --git a/persistence-modules/jooq/pom.xml b/persistence-modules/jooq/pom.xml index f0c5a27a96..cdda860040 100644 --- a/persistence-modules/jooq/pom.xml +++ b/persistence-modules/jooq/pom.xml @@ -19,28 +19,34 @@ org.jooq jooq - 3.13.4 + ${jooq.version} org.jooq jooq-meta - 3.13.4 + ${jooq.version} org.jooq jooq-codegen - 3.13.4 + ${jooq.version} org.postgresql postgresql - 42.2.16 + ${postgresql.version} com.h2database h2 - 1.4.200 + ${h2.version} + + 3.13.4 + 42.2.16 + 1.4.200 + + diff --git a/persistence-modules/sirix/pom.xml b/persistence-modules/sirix/pom.xml index 67de507cca..da9695081c 100644 --- a/persistence-modules/sirix/pom.xml +++ b/persistence-modules/sirix/pom.xml @@ -47,7 +47,6 @@ - UTF-8 11 0.9.3 3.8.0 diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationUnitTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationIntegrationTest.java similarity index 98% rename from persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationUnitTest.java rename to persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationIntegrationTest.java index 93083f6c4c..ac5661afbc 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationUnitTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/boot/jdbi/SpringBootJdbiApplicationIntegrationTest.java @@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j; @RunWith(SpringRunner.class) @SpringBootTest(classes = {SpringBootJdbiApplication.class, JdbiConfiguration.class}) @Slf4j -public class SpringBootJdbiApplicationUnitTest { +public class SpringBootJdbiApplicationIntegrationTest { @Autowired diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerUnitTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerIntegrationTest.java similarity index 97% rename from persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerUnitTest.java rename to persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerIntegrationTest.java index be16f8f563..6956df0b13 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerUnitTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/springboothsqldb/application/tests/CustomerControllerIntegrationTest.java @@ -20,7 +20,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers; @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc -public class CustomerControllerUnitTest { +public class CustomerControllerIntegrationTest { private static MediaType MEDIA_TYPE_JSON; diff --git a/persistence-modules/spring-data-cosmosdb/pom.xml b/persistence-modules/spring-data-cosmosdb/pom.xml index 19a66648b2..f3c913195f 100644 --- a/persistence-modules/spring-data-cosmosdb/pom.xml +++ b/persistence-modules/spring-data-cosmosdb/pom.xml @@ -14,9 +14,7 @@ - 1.8 2.3.0 - diff --git a/persistence-modules/spring-data-geode/pom.xml b/persistence-modules/spring-data-geode/pom.xml index 07aa65463c..ebdb37299e 100644 --- a/persistence-modules/spring-data-geode/pom.xml +++ b/persistence-modules/spring-data-geode/pom.xml @@ -61,7 +61,7 @@ com.mysema.maven maven-apt-plugin - 1.0 + ${maven-apt-plugin.version} generate-sources @@ -88,6 +88,7 @@ com.baeldung.springdatageode.app.ClientCacheApp 1.1.1.RELEASE 2.1.9.RELEASE + 1.0 \ No newline at end of file diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java index 7f50aa87f1..8fff82de32 100644 --- a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java @@ -50,7 +50,7 @@ public class Application implements CommandLineRunner { LOGGER.info("@@ findByFirstName() call..."); repository.findByFirstName("Franz") .forEach(person -> LOGGER.info(person.toString())); - LOGGER.info("@@ findByFirstName() call..."); + LOGGER.info("@@ updateByFirstName() call..."); repository.updateByFirstName(2L, "Date Inferno"); repository.findAll() .forEach(person -> LOGGER.info(person.toString())); diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java index 2f2329caec..b2f026fa0c 100644 --- a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java @@ -1,23 +1,20 @@ package com.baeldung.springdatajdbcintro.repository; -import java.util.List; - +import com.baeldung.springdatajdbcintro.entity.Person; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import com.baeldung.springdatajdbcintro.entity.Person; +import java.util.List; @Repository -public interface PersonRepository extends CrudRepository { +public interface PersonRepository extends CrudRepository { - @Query("select * from person where first_name=:firstName") - List findByFirstName(@Param("firstName") String firstName); + List findByFirstName(String firstName); @Modifying @Query("UPDATE person SET first_name = :name WHERE id = :id") boolean updateByFirstName(@Param("id") Long id, @Param("name") String name); - } diff --git a/persistence-modules/spring-data-jpa-annotations/README.md b/persistence-modules/spring-data-jpa-annotations/README.md index 1ee579cf6c..3892e75733 100644 --- a/persistence-modules/spring-data-jpa-annotations/README.md +++ b/persistence-modules/spring-data-jpa-annotations/README.md @@ -6,7 +6,6 @@ This module contains articles about annotations used in Spring Data JPA - [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd) - [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable) -- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation) - [Spring JPA @Embedded and @EmbeddedId](https://www.baeldung.com/spring-jpa-embedded-method-parameters) - [Programmatic Transaction Management in Spring](https://www.baeldung.com/spring-programmatic-transaction-management) - [JPA Entity Lifecycle Events](https://www.baeldung.com/jpa-entity-lifecycle-events) diff --git a/persistence-modules/spring-data-jpa-enterprise/README.md b/persistence-modules/spring-data-jpa-enterprise/README.md index 81398b1f00..42fbecc880 100644 --- a/persistence-modules/spring-data-jpa-enterprise/README.md +++ b/persistence-modules/spring-data-jpa-enterprise/README.md @@ -12,6 +12,7 @@ This module contains articles about Spring Data JPA used in enterprise applicati - [Working with Lazy Element Collections in JPA](https://www.baeldung.com/java-jpa-lazy-collections) - [Custom Naming Convention with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-custom-naming) - [Partial Data Update with Spring Data](https://www.baeldung.com/spring-data-partial-update) +- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation) ### Eclipse Config After importing the project into Eclipse, you may see the following error: diff --git a/persistence-modules/spring-data-jpa-enterprise/pom.xml b/persistence-modules/spring-data-jpa-enterprise/pom.xml index 7ff2f00fdf..12ffeee7f0 100644 --- a/persistence-modules/spring-data-jpa-enterprise/pom.xml +++ b/persistence-modules/spring-data-jpa-enterprise/pom.xml @@ -78,7 +78,7 @@ maven-compiler-plugin - 3.8.1 + ${maven-compiler-plugin.version} 1.8 1.8 @@ -86,7 +86,7 @@ org.mapstruct mapstruct-processor - 1.3.1.Final + ${mapstruct.version} @@ -98,7 +98,6 @@ 1.3.1.Final 21.0 1.12.2 - diff --git a/persistence-modules/spring-data-jpa-enterprise/src/main/java/com/baeldung/boot/daos/user/UserRepository.java b/persistence-modules/spring-data-jpa-enterprise/src/main/java/com/baeldung/boot/daos/user/UserRepository.java index 53f692ff28..cfa99414c6 100644 --- a/persistence-modules/spring-data-jpa-enterprise/src/main/java/com/baeldung/boot/daos/user/UserRepository.java +++ b/persistence-modules/spring-data-jpa-enterprise/src/main/java/com/baeldung/boot/daos/user/UserRepository.java @@ -93,6 +93,9 @@ public interface UserRepository extends JpaRepository , UserRepos @Query("delete User u where u.active = false") int deleteDeactivatedUsers(); + @Query("delete User u where u.active = false") + int deleteDeactivatedUsersWithNoModifyingAnnotation(); + @Modifying(clearAutomatically = true, flushAutomatically = true) @Query(value = "alter table USERS add column deleted int(1) not null default 0", nativeQuery = true) void addDeletedColumn(); diff --git a/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java b/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java index b2581b8034..e8841d921c 100644 --- a/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java +++ b/persistence-modules/spring-data-jpa-enterprise/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java @@ -3,6 +3,7 @@ package com.baeldung.boot.daos; import org.junit.After; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -21,6 +22,7 @@ import java.util.function.Predicate; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.*; public class UserRepositoryCommon { @@ -520,6 +522,22 @@ public class UserRepositoryCommon { assertEquals(1, deletedUsersCount); } + @Test + @Transactional + public void givenTwoUsers_whenDeleteDeactivatedUsersWithNoModifyingAnnotation_ThenException() { + User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1); + usr01.setLastLoginDate(LocalDate.now()); + User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.com", 0); + usr02.setLastLoginDate(LocalDate.of(2018, 7, 20)); + usr02.setActive(false); + + userRepository.save(usr01); + userRepository.save(usr02); + + assertThatThrownBy(() -> userRepository.deleteDeactivatedUsersWithNoModifyingAnnotation()) + .isInstanceOf(InvalidDataAccessApiUsageException.class); + } + @Test @Transactional public void givenTwoUsers_whenAddDeletedColumn_ThenUsersHaveDeletedColumn() { diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java index 72d4dea377..c7ca9f1ffd 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java @@ -162,6 +162,25 @@ public class ApplicationView { return betweenItems; } + // To get records having itemName in 'Skate Board', 'Paint' and 'Glue' + public String[] inCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(root.get("itemName").in("Skate Board", "Paint", "Glue")); + Query query = session.createQuery(cr); + final List inItemsList = query.getResultList(); + final String inItems[] = new String[inItemsList.size()]; + for (int i = 0; i < inItemsList.size(); i++) { + inItems[i] = inItemsList.get(i) + .getItemName(); + } + session.close(); + return inItems; + } + // To check if the given property is null public String[] nullCriteria() { final Session session = HibernateUtil.getHibernateSession(); diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java index 7d95e0f342..a1f88f3387 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java @@ -189,6 +189,18 @@ public class HibernateCriteriaIntegrationTest { assertArrayEquals(expectedPriceBetweenItems, av.betweenCriteria()); } + @Test + public void inCriteriaQuery() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedInList = session.createQuery("From Item where itemName in ('Skate Board', 'Paint', 'Glue')").list(); + final String expectedNameInItems[] = new String[expectedInList.size()]; + for (int i = 0; i < expectedInList.size(); i++) { + expectedNameInItems[i] = expectedInList.get(i).getItemName(); + } + session.close(); + assertArrayEquals(expectedNameInItems, av.inCriteria()); + } + @Test public void givenNewItemPrice_whenCriteriaUpdate_thenReturnAffectedResult() { diff --git a/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java new file mode 100644 index 0000000000..7edcc2cd4b --- /dev/null +++ b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java @@ -0,0 +1,96 @@ +package com.baeldung.jooq.introduction; + +import static com.baeldung.jooq.introduction.db.public_.tables.Author.AUTHOR; + +import java.util.ArrayList; +import java.util.List; + +import org.jooq.Condition; +import org.jooq.DSLContext; +import org.jooq.Record2; +import org.jooq.Result; +import org.jooq.impl.DSL; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +@ContextConfiguration(classes = PersistenceContextIntegrationTest.class) +@Transactional(transactionManager = "transactionManager") +@RunWith(SpringJUnit4ClassRunner.class) +public class CountQueryIntegrationTest { + + @Autowired + private DSLContext dsl; + + @Test + public void givenValidData_whenSimpleSelect_thenSucceed() { + int count = dsl.select().from(AUTHOR).execute(); + Assert.assertEquals(3, count); + } + + @Test + public void givenValidData_whenSelectCount_thenSucceed() { + int count = dsl.selectCount().from(AUTHOR) + .where(AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan")) + .fetchOne(0, int.class); + Assert.assertEquals(1, count); + } + + @Test + public void givenValidData_whenCount_thenSucceed() { + int count = dsl.select(DSL.count()) + .from(AUTHOR).fetchOne(0, int.class); + Assert.assertEquals(3, count); + } + + @Test + public void givenValidData_whenFetchCount_thenSucceed() { + int count = dsl.fetchCount(DSL.selectFrom(AUTHOR) + .where(AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan"))); + Assert.assertEquals(1, count); + } + + @Test + public void givenValidData_whenFetchCountWithoutCondition_thenSucceed() { + int count = dsl.fetchCount(DSL.selectFrom(AUTHOR)); + Assert.assertEquals(3, count); + } + + @Test + public void givenValidData_whenFetchCountWithSingleCondition_thenSucceed() { + int count = dsl.fetchCount(AUTHOR, AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan")); + Assert.assertEquals(1, count); + } + + @Test + public void givenValidData_whenFetchCountWithMultipleConditions_thenSucceed() { + Condition firstCond = AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan"); + Condition secondCond = AUTHOR.ID.notEqual(1); + List conditions = new ArrayList<>(); + conditions.add(firstCond); + conditions.add(secondCond); + int count = dsl.fetchCount(AUTHOR, conditions); + Assert.assertEquals(1, count); + } + + @Test + public void givenValidData_whenFetchCountWithConditionsInVarargs_thenSucceed() { + Condition firstCond = AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan"); + Condition secondCond = AUTHOR.ID.notEqual(1); + int count = dsl.fetchCount(AUTHOR, firstCond, secondCond); + Assert.assertEquals(1, count); + } + + @Test + public void givenValidData_whenCountwithGroupBy_thenSucceed() { + final Result> result = dsl.select(AUTHOR.FIRST_NAME, DSL.count()) + .from(AUTHOR).groupBy(AUTHOR.FIRST_NAME).fetch(); + Assert.assertEquals(3, result.size()); + Assert.assertEquals(result.get(0).get(0), "Bert"); + Assert.assertEquals(result.get(0).get(1), 1); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-jpa-2/pom.xml b/persistence-modules/spring-jpa-2/pom.xml index 7770c0e045..52067f3e5e 100644 --- a/persistence-modules/spring-jpa-2/pom.xml +++ b/persistence-modules/spring-jpa-2/pom.xml @@ -66,11 +66,6 @@ guava ${guava.version} - - net.bytebuddy - byte-buddy - ${byte-buddy.version} - @@ -97,7 +92,6 @@ 21.0 - 1.10.16 \ No newline at end of file diff --git a/pom.xml b/pom.xml index c697abe179..78a6d8d329 100644 --- a/pom.xml +++ b/pom.xml @@ -471,7 +471,7 @@ json-path jsoup jta - + kubernetes language-interop libraries-2 @@ -531,7 +531,7 @@ protobuffer quarkus - + quarkus-extension rabbitmq @@ -1351,13 +1351,13 @@ false false false - true + true 4.12 2.2 1.3 3.3.0 - 1.10.5 + 1.10.22 1.7.30 @@ -1370,9 +1370,9 @@ 1.6.0 1.8 1.2.17 - 2.1.0.1 - 1.19 - 1.19 + 2.2.2.0 + 1.28 + 1.28 1.6.0 2.21.0 2.8.0 diff --git a/quarkus-extension/quarkus-app/pom.xml b/quarkus-extension/quarkus-app/pom.xml index 6d3f4c7c28..4c9e9c3cc7 100644 --- a/quarkus-extension/quarkus-app/pom.xml +++ b/quarkus-extension/quarkus-app/pom.xml @@ -27,9 +27,10 @@ com.baeldung.quarkus.liquibase - quarkus-liquibase-runtime + runtime ${project.version} + io.quarkus quarkus-jdbc-h2 diff --git a/quarkus-extension/quarkus-liquibase/deployment/pom.xml b/quarkus-extension/quarkus-liquibase/deployment/pom.xml index d7f1f995ff..42d3ca2810 100644 --- a/quarkus-extension/quarkus-liquibase/deployment/pom.xml +++ b/quarkus-extension/quarkus-liquibase/deployment/pom.xml @@ -3,6 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + com.baeldung.quarkus.liquibase deployment deployment @@ -30,7 +31,7 @@ com.baeldung.quarkus.liquibase - quarkus-liquibase-runtime + runtime ${project.version} diff --git a/quarkus-extension/quarkus-liquibase/runtime/pom.xml b/quarkus-extension/quarkus-liquibase/runtime/pom.xml index 5d3b05ef92..0250d34711 100644 --- a/quarkus-extension/quarkus-liquibase/runtime/pom.xml +++ b/quarkus-extension/quarkus-liquibase/runtime/pom.xml @@ -2,6 +2,7 @@ 4.0.0 + com.baeldung.quarkus.liquibase runtime runtime @@ -41,7 +42,7 @@ extension-descriptor - ${project.groupId}:quarkus-liquibase-deployment:${project.version} + ${project.groupId}:deployment:${project.version} diff --git a/quarkus/pom.xml b/quarkus/pom.xml index 9c14afca3c..9826fd1034 100644 --- a/quarkus/pom.xml +++ b/quarkus/pom.xml @@ -97,7 +97,6 @@ maven-surefire-plugin - ${surefire-plugin.version} 1 true @@ -136,7 +135,6 @@ maven-failsafe-plugin - ${surefire-plugin.version} @@ -157,7 +155,6 @@ - 2.22.0 1.7.0.Final 5.6.0 diff --git a/reactive-systems/inventory-service/pom.xml b/reactive-systems/inventory-service/pom.xml index 4c04afb5cb..b5ec210636 100644 --- a/reactive-systems/inventory-service/pom.xml +++ b/reactive-systems/inventory-service/pom.xml @@ -15,10 +15,6 @@ ../../parent-boot-2 - - 1.8 - - org.springframework.boot diff --git a/reactive-systems/order-service/pom.xml b/reactive-systems/order-service/pom.xml index c793f448b5..603f0373ba 100644 --- a/reactive-systems/order-service/pom.xml +++ b/reactive-systems/order-service/pom.xml @@ -15,10 +15,6 @@ ../../parent-boot-2 - - 1.8 - - org.springframework.boot diff --git a/reactive-systems/shipping-service/pom.xml b/reactive-systems/shipping-service/pom.xml index 72487e691e..458b91b6ce 100644 --- a/reactive-systems/shipping-service/pom.xml +++ b/reactive-systems/shipping-service/pom.xml @@ -15,10 +15,6 @@ ../../parent-boot-2 - - 1.8 - - org.springframework.boot diff --git a/spring-5-reactive-client/pom.xml b/spring-5-reactive-client/pom.xml index 7ae7ba6edd..28f692a735 100644 --- a/spring-5-reactive-client/pom.xml +++ b/spring-5-reactive-client/pom.xml @@ -150,21 +150,6 @@ 1.8 - - maven-surefire-plugin - 2.22.0 - - - maven-surefire-plugin - 2.19.1 - - - org.junit.platform - junit-platform-surefire-provider - 1.0.1 - - - @@ -174,7 +159,7 @@ 1.0 1.0 4.1 - 1.0.3 + 1.1.6 4.0.1 diff --git a/spring-5/pom.xml b/spring-5/pom.xml index e368bcacba..082b1f8a87 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -142,7 +142,6 @@ 1.5.6 4.1 ${project.build.directory}/generated-snippets - 2.21.0 diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 4902368d7e..0288b03928 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -106,17 +106,8 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - - 5.6.2 + 2.22.2 diff --git a/spring-boot-modules/spring-boot-actuator/pom.xml b/spring-boot-modules/spring-boot-actuator/pom.xml index a808b8cb1b..3cb324a0b8 100644 --- a/spring-boot-modules/spring-boot-actuator/pom.xml +++ b/spring-boot-modules/spring-boot-actuator/pom.xml @@ -28,6 +28,10 @@ org.springframework.boot spring-boot-starter-data-jpa + + org.springframework.boot + spring-boot-starter-security + com.h2database h2 @@ -44,6 +48,11 @@ + + org.springframework.security + spring-security-test + test + @@ -53,6 +62,7 @@ spring-boot-maven-plugin com.baeldung.probes.ProbesApplication + com.baeldung.endpoints.enabling.EndpointEnablingApplication diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/endpoints/enabling/EndpointEnablingApplication.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/endpoints/enabling/EndpointEnablingApplication.java new file mode 100644 index 0000000000..2e8024dcd5 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/endpoints/enabling/EndpointEnablingApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.endpoints.enabling; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class }, scanBasePackages = "com.baeldung.endpoints.enabling") +public class EndpointEnablingApplication { + + public static void main(String[] args) { + SpringApplication.run(EndpointEnablingApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/endpoints/enabling/SecurityConfiguration.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/endpoints/enabling/SecurityConfiguration.java new file mode 100644 index 0000000000..24b78642f2 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/endpoints/enabling/SecurityConfiguration.java @@ -0,0 +1,36 @@ +package com.baeldung.endpoints.enabling; + +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +@EnableWebSecurity +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + auth.inMemoryAuthentication() + .withUser("user") + .password(encoder.encode("password")) + .roles("USER") + .and() + .withUser("admin") + .password(encoder.encode("admin")) + .roles("USER", "ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.requestMatcher(EndpointRequest.toAnyEndpoint()) + .authorizeRequests((requests) -> requests.anyRequest() + .hasRole("ADMIN")); + http.httpBasic(); + } +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/resources/application.properties b/spring-boot-modules/spring-boot-actuator/src/main/resources/application.properties index de7be417a8..e69c763eeb 100644 --- a/spring-boot-modules/spring-boot-actuator/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-actuator/src/main/resources/application.properties @@ -11,3 +11,6 @@ info.app.name=Spring Sample Application info.app.description=This is my first spring boot application G1 info.app.version=1.0.0 info.java-vendor = ${java.specification.vendor} + +management.endpoints.web.exposure.include=* +management.endpoint.shutdown.enabled=true diff --git a/spring-boot-modules/spring-boot-actuator/src/test/java/com/baeldung/endpoints/enabling/EndpointEnablingIntegrationTest.java b/spring-boot-modules/spring-boot-actuator/src/test/java/com/baeldung/endpoints/enabling/EndpointEnablingIntegrationTest.java new file mode 100644 index 0000000000..8a9dd4ca72 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/test/java/com/baeldung/endpoints/enabling/EndpointEnablingIntegrationTest.java @@ -0,0 +1,36 @@ +package com.baeldung.endpoints.enabling; + +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.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; + +@SpringBootTest +@AutoConfigureMockMvc +public class EndpointEnablingIntegrationTest { + @Autowired + private MockMvc mockMvc; + + @Test + @WithMockUser(username = "user", password = "password", roles = "USER") + public void givenWrongAuthentication_whenCallingActuator_thenReturns401() throws Exception { + mockMvc.perform(get("/actuator")) + .andExpect(status().isForbidden()); + } + + @Test + @WithMockUser(username = "admin", password = "admin", roles = "ADMIN") + public void givenProperAuthentication_whenCallingActuator_thenReturnsExpectedEndpoints() throws Exception { + mockMvc.perform(get("/actuator")) + .andExpect(jsonPath("$._links").exists()) + .andExpect(jsonPath("$._links.beans").exists()) + .andExpect(jsonPath("$._links.env").exists()) + .andExpect(jsonPath("$._links.shutdown").exists()); + } +} diff --git a/spring-boot-modules/spring-boot-autoconfiguration/pom.xml b/spring-boot-modules/spring-boot-autoconfiguration/pom.xml index 269d87bbb9..4990e6884c 100644 --- a/spring-boot-modules/spring-boot-autoconfiguration/pom.xml +++ b/spring-boot-modules/spring-boot-autoconfiguration/pom.xml @@ -48,7 +48,6 @@ org.springframework.boot spring-boot-configuration-processor - 2.1.6.RELEASE true diff --git a/spring-boot-modules/spring-boot-bootstrap/pom.xml b/spring-boot-modules/spring-boot-bootstrap/pom.xml index 6a1be7a2c8..5f1cd8fb65 100644 --- a/spring-boot-modules/spring-boot-bootstrap/pom.xml +++ b/spring-boot-modules/spring-boot-bootstrap/pom.xml @@ -167,7 +167,7 @@ org.springframework.cloud spring-cloud-dependencies - Greenwich.RELEASE + ${spring-cloud.version} pom import @@ -177,12 +177,12 @@ org.springframework.cloud spring-cloud-gcp-starter - 1.0.0.RELEASE + ${spring-cloud-gcp.version} org.springframework.cloud spring-cloud-gcp-starter-sql-mysql - 1.0.0.RELEASE + ${spring-cloud-gcp.version} @@ -215,7 +215,7 @@ org.springframework.cloud spring-cloud-dependencies - Greenwich.RELEASE + ${spring-cloud.version} pom import @@ -332,6 +332,8 @@ 4.0.0 + Greenwich.RELEASE + 1.0.0.RELEASE diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml index 532f45cf3e..4903f21c77 100644 --- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml @@ -62,7 +62,6 @@ - UTF-8 2.2.6.RELEASE 0.0.1-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml index 0e8fb4cbc9..85a6721492 100644 --- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml @@ -49,7 +49,6 @@ - UTF-8 0.0.1-SNAPSHOT 2.2.6.RELEASE diff --git a/spring-boot-modules/spring-boot-data-2/README.md b/spring-boot-modules/spring-boot-data-2/README.md index 29d9dafe66..875ee502b4 100644 --- a/spring-boot-modules/spring-boot-data-2/README.md +++ b/spring-boot-modules/spring-boot-data-2/README.md @@ -2,3 +2,4 @@ - [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) +- [Creating a Read-Only Repository with Spring Data](https://www.baeldung.com/spring-data-read-only-repository) diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java new file mode 100644 index 0000000000..ff0a8a1bb3 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/Book.java @@ -0,0 +1,39 @@ +package com.baeldung.boot.readonlyrepository; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Book +{ + @Id + @GeneratedValue + private Long id; + private String author; + private String title; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/BookReadOnlyRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/BookReadOnlyRepository.java new file mode 100644 index 0000000000..6327ef5a56 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/BookReadOnlyRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.boot.readonlyrepository; + +import java.util.List; + +public interface BookReadOnlyRepository extends ReadOnlyRepository { + + List findByAuthor(String author); + + List findByTitle(String title); +} diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepository.java new file mode 100644 index 0000000000..16f3fd429e --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.boot.readonlyrepository; + +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.Repository; + +import java.util.List; +import java.util.Optional; + +@NoRepositoryBean +public interface ReadOnlyRepository extends Repository { + + Optional findById(ID id); + + List findAll(); +} diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryApplication.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryApplication.java new file mode 100644 index 0000000000..f5a67197ad --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.boot.readonlyrepository; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ReadOnlyRepositoryApplication { + + public static void main(String[] args) { + SpringApplication.run(ReadOnlyRepositoryApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java new file mode 100644 index 0000000000..363b310c8c --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/BookRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.boot.readonlyrepository; + +import org.springframework.data.repository.CrudRepository; + +public interface BookRepository extends BookReadOnlyRepository, CrudRepository { +} diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryUnitTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryUnitTest.java new file mode 100644 index 0000000000..cdb6065f23 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/readonlyrepository/ReadOnlyRepositoryUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.boot.readonlyrepository; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; +import java.util.NoSuchElementException; + +@SpringBootTest( classes = ReadOnlyRepositoryApplication.class ) +public class ReadOnlyRepositoryUnitTest +{ + @Autowired + private BookRepository bookRepository; + + @Autowired + private BookReadOnlyRepository bookReadOnlyRepository; + + @Test + public void givenBooks_whenUsingReadOnlyRepository_thenGetThem() { + Book aChristmasCarolCharlesDickens = new Book(); + aChristmasCarolCharlesDickens.setTitle("A Christmas Carol"); + aChristmasCarolCharlesDickens.setAuthor("Charles Dickens"); + bookRepository.save(aChristmasCarolCharlesDickens); + + Book greatExpectationsCharlesDickens = new Book(); + greatExpectationsCharlesDickens.setTitle("Great Expectations"); + greatExpectationsCharlesDickens.setAuthor("Charles Dickens"); + bookRepository.save(greatExpectationsCharlesDickens); + + Book greatExpectationsKathyAcker = new Book(); + greatExpectationsKathyAcker.setTitle("Great Expectations"); + greatExpectationsKathyAcker.setAuthor("Kathy Acker"); + bookRepository.save(greatExpectationsKathyAcker); + + List charlesDickensBooks = bookReadOnlyRepository.findByAuthor("Charles Dickens"); + Assertions.assertEquals(2, charlesDickensBooks.size()); + + List greatExpectationsBooks = bookReadOnlyRepository.findByTitle("Great Expectations"); + Assertions.assertEquals(2, greatExpectationsBooks.size()); + + List allBooks = bookReadOnlyRepository.findAll(); + Assertions.assertEquals(3, allBooks.size()); + + Long bookId = allBooks.get(0).getId(); + Book book = bookReadOnlyRepository.findById(bookId).orElseThrow(NoSuchElementException::new); + Assertions.assertNotNull(book); + } +} diff --git a/spring-boot-modules/spring-boot-deployment/pom.xml b/spring-boot-modules/spring-boot-deployment/pom.xml index 94a4018103..ae546016f2 100644 --- a/spring-boot-modules/spring-boot-deployment/pom.xml +++ b/spring-boot-modules/spring-boot-deployment/pom.xml @@ -84,12 +84,6 @@ ${jquery.version} - - org.springframework.cloud - spring-cloud-context - ${springcloud.version} - - org.apache.httpcomponents httpclient @@ -195,9 +189,7 @@ 2.2 18.0 3.1.7 - 2.0.2.RELEASE 4.5.8 - 2.3.3.RELEASE diff --git a/spring-boot-modules/spring-boot-libraries-2/pom.xml b/spring-boot-modules/spring-boot-libraries-2/pom.xml index 35dec54450..629b713cb5 100644 --- a/spring-boot-modules/spring-boot-libraries-2/pom.xml +++ b/spring-boot-modules/spring-boot-libraries-2/pom.xml @@ -16,6 +16,14 @@ org.springframework.boot spring-boot-starter-web + + ch.qos.logback + logback-classic + + + org.springframework.data + spring-data-jpa + @@ -23,6 +31,23 @@ jobrunr-spring-boot-starter ${jobrunr.version} + + + + org.openapitools + openapi-generator + ${openapi-generator.version} + + + org.openapitools + jackson-databind-nullable + ${jackson-databind.version} + + + io.springfox + springfox-swagger2 + ${springfox.version} + org.springframework.boot @@ -37,10 +62,45 @@ test + + + + + org.openapitools + openapi-generator-maven-plugin + ${openapi-generator.version} + + + + generate + + + + ${project.basedir}/src/main/resources/petstore.yml + + spring + com.baeldung.openapi.api + com.baeldung.openapi.model + + ApiUtil.java + + + true + + + + + + + 1.1.0 4.0.3 + 5.1.0 + 2.4.5 + 0.2.1 + 2.9.2 diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/jobrunr/JobRunrSpringBootApp.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/JobRunrSpringBootApp.java similarity index 97% rename from spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/jobrunr/JobRunrSpringBootApp.java rename to spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/JobRunrSpringBootApp.java index d72e9464d9..77297feb92 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/jobrunr/JobRunrSpringBootApp.java +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/JobRunrSpringBootApp.java @@ -1,4 +1,4 @@ -package com.baeldung.jobrunr; +package com.baeldung; import com.baeldung.jobrunr.service.SampleJobService; import org.jobrunr.jobs.mappers.JobMapper; diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/resources/petstore.yml b/spring-boot-modules/spring-boot-libraries-2/src/main/resources/petstore.yml new file mode 100644 index 0000000000..3265a18c3e --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/main/resources/petstore.yml @@ -0,0 +1,111 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: http://localhost:8080/ +paths: + /pets: + get: + summary: List all pets + operationId: listPets + tags: + - pets + parameters: + - name: limit + in: query + description: How many items to return at one time (max 100) + required: false + schema: + type: integer + format: int32 + responses: + '200': + description: A paged array of pets + headers: + x-next: + description: A link to the next page of responses + schema: + type: string + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + post: + summary: Create a pet + operationId: createPets + tags: + - pets + responses: + '201': + description: Null response + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/jobrunr/JobRunrLiveTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/jobrunr/JobRunrLiveTest.java index 83222e7726..2c259b6879 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/jobrunr/JobRunrLiveTest.java +++ b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/jobrunr/JobRunrLiveTest.java @@ -10,6 +10,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.JobRunrSpringBootApp; + import java.net.URI; import java.util.concurrent.TimeUnit; diff --git a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/openapi/OpenApiPetsIntegrationTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/openapi/OpenApiPetsIntegrationTest.java new file mode 100644 index 0000000000..b56c19d94c --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/openapi/OpenApiPetsIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.openapi; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +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.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class OpenApiPetsIntegrationTest { + + private static final String PETS_PATH = "/pets/"; + + @Autowired + private MockMvc mockMvc; + + @Test + public void whenReadAll_thenStatusIsNotImplemented() throws Exception { + this.mockMvc.perform(get(PETS_PATH)) + .andExpect(status().isNotImplemented()); + } + + @Test + public void whenReadOne_thenStatusIsNotImplemented() throws Exception { + this.mockMvc.perform(get(PETS_PATH + 1)) + .andExpect(status().isNotImplemented()); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java b/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java index 6dcbfe390f..8467a25acd 100644 --- a/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java +++ b/spring-boot-modules/spring-boot-mvc-3/src/test/java/com/baeldung/charencoding/controller/CharEncodingCheckControllerUnitTest.java @@ -1,34 +1,35 @@ package com.baeldung.charencoding.controller; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import java.io.IOException; +import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.web.filter.CharacterEncodingFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; -import org.junit.jupiter.api.Test; -import org.springframework.web.filter.CharacterEncodingFilter; +import static org.junit.jupiter.api.Assertions.assertEquals; class CharEncodingCheckControllerUnitTest { @Test void whenCharEncodingFilter_thenVerifyEncoding() throws ServletException, IOException { - HttpServletRequest request = mock(HttpServletRequest.class); - HttpServletResponse response = mock(HttpServletResponse.class); - FilterChain chain = mock(FilterChain.class); - + HttpServletRequest request = new MockHttpServletRequest(); + HttpServletResponse response = new MockHttpServletResponse(); + FilterChain chain = new MockFilterChain(); + CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding("UTF-8"); filter.setForceEncoding(true); - + filter.doFilter(request, response, chain); - - verify(request).setCharacterEncoding("UTF-8"); - verify(response).setCharacterEncoding("UTF-8"); + + assertEquals("UTF-8", request.getCharacterEncoding()); + assertEquals("UTF-8", response.getCharacterEncoding()); } } diff --git a/spring-boot-modules/spring-boot-mvc-jersey/README.md b/spring-boot-modules/spring-boot-mvc-jersey/README.md index 07f9e78ea6..192658c4a5 100644 --- a/spring-boot-modules/spring-boot-mvc-jersey/README.md +++ b/spring-boot-modules/spring-boot-mvc-jersey/README.md @@ -5,4 +5,4 @@ This module contains articles about Spring Boot: JAX-RS vs Spring ### Relevant Articles: -- [REST API: JAX-RS vs Spring](https://www.baeldung.com/TBD) +- [REST API: JAX-RS vs Spring](https://www.baeldung.com/rest-api-jax-rs-vs-spring) diff --git a/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml index 5f5d3a9f6a..63d6078eca 100644 --- a/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml +++ b/spring-boot-modules/spring-boot-parent/spring-boot-with-custom-parent/pom.xml @@ -23,8 +23,4 @@ - - 1.8 - - diff --git a/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml index 108e66b68e..4274f63aa3 100644 --- a/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml +++ b/spring-boot-modules/spring-boot-parent/spring-boot-with-starter-parent/pom.xml @@ -39,7 +39,6 @@ - 1.8 2.2.5.RELEASE diff --git a/spring-boot-modules/spring-boot-properties-3/pom.xml b/spring-boot-modules/spring-boot-properties-3/pom.xml index 809fd6e2d4..33799b557d 100644 --- a/spring-boot-modules/spring-boot-properties-3/pom.xml +++ b/spring-boot-modules/spring-boot-properties-3/pom.xml @@ -14,9 +14,6 @@ spring-boot-properties-3 Spring Boot Properties Module - - 1.8 - org.springframework.boot diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java index 8040c93ee0..e02d1de272 100644 --- a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java +++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java @@ -2,6 +2,7 @@ package com.baeldung.boot.properties.multidocument; import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; @@ -21,6 +22,7 @@ public class StagingMultidocumentFilesIntegrationTest { private String baelRootProperty; @Test + @Disabled("Fix and update https://www.baeldung.com/spring-boot-yaml-vs-properties article") public void givenProductionProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() { assertThat(baelCustomProperty).isEqualTo("stagingValue"); assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue"); diff --git a/spring-boot-modules/spring-boot-properties/pom.xml b/spring-boot-modules/spring-boot-properties/pom.xml index 40668f47fd..0a7d8a8cbf 100644 --- a/spring-boot-modules/spring-boot-properties/pom.xml +++ b/spring-boot-modules/spring-boot-properties/pom.xml @@ -134,7 +134,6 @@ - 1.8 2020.0.0-M5 1.10 20.0 diff --git a/spring-boot-modules/spring-boot-security/pom.xml b/spring-boot-modules/spring-boot-security/pom.xml index 33b7cbfd74..3f8d2ff73f 100644 --- a/spring-boot-modules/spring-boot-security/pom.xml +++ b/spring-boot-modules/spring-boot-security/pom.xml @@ -71,7 +71,6 @@ org.springframework.boot spring-boot-autoconfigure - diff --git a/spring-boot-modules/spring-boot-springdoc/pom.xml b/spring-boot-modules/spring-boot-springdoc/pom.xml index 259383a1d2..8442504fed 100644 --- a/spring-boot-modules/spring-boot-springdoc/pom.xml +++ b/spring-boot-modules/spring-boot-springdoc/pom.xml @@ -169,7 +169,6 @@ - 1.8 5.2.10.Final 1.5.2 1.5.6 diff --git a/spring-boot-modules/spring-boot-swagger-jwt/pom.xml b/spring-boot-modules/spring-boot-swagger-jwt/pom.xml index d71d7342ce..6ee7db2ac9 100644 --- a/spring-boot-modules/spring-boot-swagger-jwt/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-jwt/pom.xml @@ -25,7 +25,7 @@ io.springfox springfox-boot-starter - 3.0.0 + ${springfox.version} @@ -38,4 +38,8 @@ + + 3.0.0 + + diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index 4e0180460d..2d80cae4d5 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -25,7 +25,7 @@ io.springfox springfox-boot-starter - 3.0.0 + ${springfox.version} @@ -38,4 +38,8 @@ + + 3.0.0 + + diff --git a/spring-boot-rest-2/README.md b/spring-boot-rest-2/README.md new file mode 100644 index 0000000000..f09159198c --- /dev/null +++ b/spring-boot-rest-2/README.md @@ -0,0 +1,3 @@ +### Relevant Article: + +- [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints) diff --git a/spring-boot-rest-2/pom.xml b/spring-boot-rest-2/pom.xml new file mode 100644 index 0000000000..d74c393f27 --- /dev/null +++ b/spring-boot-rest-2/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + com.baeldung.web + spring-boot-rest-2 + spring-boot-rest-2 + war + Spring Boot Rest Module + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.springfox + springfox-boot-starter + 3.0.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java new file mode 100644 index 0000000000..510e208f9e --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.endpoint; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootRestApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootRestApplication.class, args); + } +} diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java new file mode 100644 index 0000000000..732b298981 --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java @@ -0,0 +1,15 @@ +package com.baeldung.endpoint.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping("/hello") + public ResponseEntity hello() { + return ResponseEntity.ok("hello baeldung"); + } + +} diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java new file mode 100644 index 0000000000..c57f6b5ecd --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java @@ -0,0 +1,27 @@ +package com.baeldung.endpoint.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.Map; + +@Configuration +public class AnnotationDrivenEndpointsListener { + private final Logger LOGGER = LoggerFactory.getLogger("AnnotationDrivenEndpointsListener.class"); + + @EventListener + public void handleContextRefresh(ContextRefreshedEvent event) { + ApplicationContext applicationContext = event.getApplicationContext(); + RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext + .getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); + Map map = requestMappingHandlerMapping.getHandlerMethods(); + map.forEach((key, value) -> LOGGER.info("{} {}", key, value)); + } +} diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java new file mode 100644 index 0000000000..ae00fc3927 --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java @@ -0,0 +1,27 @@ +package com.baeldung.endpoint.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.Map; + +@Configuration +public class EndpointsListener implements ApplicationListener { + private final Logger LOGGER = LoggerFactory.getLogger("EndpointsListener.class"); + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + ApplicationContext applicationContext = event.getApplicationContext(); + RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext + .getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); + Map map = requestMappingHandlerMapping.getHandlerMethods(); + map.forEach((key, value) -> LOGGER.info("{} {}", key, value)); + } +} diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java new file mode 100644 index 0000000000..bd258122cd --- /dev/null +++ b/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java @@ -0,0 +1,21 @@ +package com.baeldung.endpoint.swagger; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +@Configuration +public class SpringFoxConfig { + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build(); + } +} diff --git a/spring-boot-rest-2/src/main/resources/application.properties b/spring-boot-rest-2/src/main/resources/application.properties new file mode 100644 index 0000000000..5046c9660f --- /dev/null +++ b/spring-boot-rest-2/src/main/resources/application.properties @@ -0,0 +1,2 @@ + +management.endpoints.web.exposure.include=mappings diff --git a/spring-caching/pom.xml b/spring-caching/pom.xml index f58be35a76..c620072604 100644 --- a/spring-caching/pom.xml +++ b/spring-caching/pom.xml @@ -71,15 +71,9 @@ org.springframework.boot spring-boot-starter-data-jpa - - net.bytebuddy - byte-buddy - 1.10.11 - org.springframework.data spring-data-commons - 2.3.0.RELEASE diff --git a/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml b/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml index a32bd5a2d3..2ebc673ef4 100644 --- a/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/order-service/pom.xml @@ -112,7 +112,6 @@ - 1.8 2.6 0.0.2 1.8 diff --git a/spring-cloud/spring-cloud-connectors-heroku/pom.xml b/spring-cloud/spring-cloud-connectors-heroku/pom.xml index e71e1350a2..d318aa3c64 100644 --- a/spring-cloud/spring-cloud-connectors-heroku/pom.xml +++ b/spring-cloud/spring-cloud-connectors-heroku/pom.xml @@ -35,11 +35,6 @@ org.postgresql postgresql - - net.bytebuddy - byte-buddy-dep - ${bytebuddy.version} - com.h2database h2 @@ -63,8 +58,6 @@ 2.2.6.RELEASE Hoxton.SR4 42.2.10 - 1.10.10 - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml index f0d34d2231..16e718a3be 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/liveness-example/pom.xml @@ -41,9 +41,4 @@ - - UTF-8 - UTF-8 - - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/readiness-example/pom.xml b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/readiness-example/pom.xml index 8bfd4d305d..0ee40b6504 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/readiness-example/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-selfhealing/readiness-example/pom.xml @@ -41,9 +41,4 @@ - - UTF-8 - UTF-8 - - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml index 52230dd1c1..32a31c3042 100644 --- a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/pom.xml @@ -101,7 +101,6 @@ - 1.8 Greenwich.SR1 4.0.0 1.8.2 diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml b/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml index 4e6b8b8b6c..fd10322efb 100644 --- a/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml @@ -45,13 +45,6 @@ org.springframework.cloud spring-cloud-task-batch - - - net.bytebuddy - byte-buddy-dep - ${bytebuddy.version} - - com.h2database h2 @@ -70,7 +63,6 @@ com.baeldung.TaskDemo - 1.10.10 diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml index c7b35ef934..c6658d70a2 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml @@ -22,7 +22,6 @@ - UTF-8 3.7.0 1.4.2.RELEASE 1.10 diff --git a/spring-cloud/spring-cloud-zuul-fallback/pom.xml b/spring-cloud/spring-cloud-zuul-fallback/pom.xml index cb762eb099..42925a6ab9 100644 --- a/spring-cloud/spring-cloud-zuul-fallback/pom.xml +++ b/spring-cloud/spring-cloud-zuul-fallback/pom.xml @@ -21,7 +21,6 @@ - 1.8 Finchley.SR2 3.1.1 diff --git a/spring-cloud/spring-cloud-zuul/pom.xml b/spring-cloud/spring-cloud-zuul/pom.xml index 6035ba7e59..13834848fe 100644 --- a/spring-cloud/spring-cloud-zuul/pom.xml +++ b/spring-cloud/spring-cloud-zuul/pom.xml @@ -38,6 +38,11 @@ pom import + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + ${spring-cloud-netflix-zuul.version} + @@ -46,10 +51,6 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.cloud - spring-cloud-starter-netflix-zuul - com.h2database h2 @@ -79,8 +80,8 @@ - Hoxton.SR4 - 2.3.3.RELEASE + 2020.0.0 + 2.2.2.RELEASE diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml index b42d32b6b3..bb735a71ed 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/pom.xml @@ -19,6 +19,10 @@ spring-cloud-zuul-ratelimit ${rate.limit.version} + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + org.springframework.boot spring-boot-starter-data-jpa diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml index 7978d9c77b..b7e1702558 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/pom.xml @@ -13,6 +13,10 @@ + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + org.springframework.boot spring-boot-starter-thymeleaf diff --git a/spring-core-3/pom.xml b/spring-core-3/pom.xml index 205259e8e4..618800529c 100644 --- a/spring-core-3/pom.xml +++ b/spring-core-3/pom.xml @@ -69,18 +69,7 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.surefire.version} - - - - - 2.22.1 1.3.2 2.2.2.RELEASE diff --git a/spring-core-4/pom.xml b/spring-core-4/pom.xml index df0b90fef2..d2e948c475 100644 --- a/spring-core-4/pom.xml +++ b/spring-core-4/pom.xml @@ -87,18 +87,7 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.surefire.version} - - - - - 2.22.1 1.3.2 2.2.2.RELEASE 28.2-jre diff --git a/spring-core-5/pom.xml b/spring-core-5/pom.xml index 743002c137..05ee1c5f5d 100644 --- a/spring-core-5/pom.xml +++ b/spring-core-5/pom.xml @@ -25,22 +25,16 @@ ${spring-boot-starter.version} test + + org.projectlombok + lombok + ${lombok.version} + - - - - 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/autoproxying/DataCache.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/DataCache.java new file mode 100644 index 0000000000..bc92d0a1d9 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/DataCache.java @@ -0,0 +1,12 @@ +package com.baeldung.component.autoproxying; + +import lombok.Getter; +import org.springframework.stereotype.Component; + +@Getter +@Component +public class DataCache { + @RandomInt(min = 2, max = 10) + private int group; + private String name; +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java new file mode 100644 index 0000000000..1fa9aa376f --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java @@ -0,0 +1,33 @@ +package com.baeldung.component.autoproxying; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Lazy; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +public class EligibleForAutoProxyRandomIntProcessor implements BeanPostProcessor { + private final RandomIntGenerator randomIntGenerator; + + @Lazy + public EligibleForAutoProxyRandomIntProcessor(RandomIntGenerator randomIntGenerator) { + this.randomIntGenerator = randomIntGenerator; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + Field[] fields = bean.getClass().getDeclaredFields(); + for (Field field : fields) { + RandomInt injectRandomInt = field.getAnnotation(RandomInt.class); + if (injectRandomInt != null) { + int min = injectRandomInt.min(); + int max = injectRandomInt.max(); + int randomValue = randomIntGenerator.generate(min, max); + field.setAccessible(true); + ReflectionUtils.setField(field, bean, randomValue); + } + } + return bean; + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java new file mode 100644 index 0000000000..d02780011c --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java @@ -0,0 +1,31 @@ +package com.baeldung.component.autoproxying; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +public class NotEligibleForAutoProxyRandomIntProcessor implements BeanPostProcessor { + private final RandomIntGenerator randomIntGenerator; + + public NotEligibleForAutoProxyRandomIntProcessor(RandomIntGenerator randomIntGenerator) { + this.randomIntGenerator = randomIntGenerator; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + Field[] fields = bean.getClass().getDeclaredFields(); + for (Field field : fields) { + RandomInt injectRandomInt = field.getAnnotation(RandomInt.class); + if (injectRandomInt != null) { + int min = injectRandomInt.min(); + int max = injectRandomInt.max(); + int randomValue = randomIntGenerator.generate(min, max); + field.setAccessible(true); + ReflectionUtils.setField(field, bean, randomValue); + } + } + return bean; + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java new file mode 100644 index 0000000000..c7881af4af --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java @@ -0,0 +1,11 @@ +package com.baeldung.component.autoproxying; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface RandomInt { + int min(); + + int max(); +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java new file mode 100644 index 0000000000..d0d44c3333 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java @@ -0,0 +1,21 @@ +package com.baeldung.component.autoproxying; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Random; + +@Slf4j +@Component +public class RandomIntGenerator { + private final Random random = new Random(); + private final DataCache dataCache; + + public RandomIntGenerator(DataCache dataCache) { + this.dataCache = dataCache; + } + + public int generate(int min, int max) { + return random.nextInt(max - min) + min; + } +} diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java new file mode 100644 index 0000000000..4af700813a --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java @@ -0,0 +1,49 @@ +package com.baeldung.component.autoproxying; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.ILoggingEvent; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {EligibleForAutoProxyRandomIntProcessor.class, DataCache.class, RandomIntGenerator.class}) +public class EligibleForAutoProxyingIntegrationTest { + private static MemoryLogAppender memoryAppender; + + private EligibleForAutoProxyRandomIntProcessor randomIntProcessor; + + @Autowired + private DataCache dataCache; + + @BeforeClass + public static void setup() { + memoryAppender = new MemoryLogAppender(); + memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); + + Logger logger = (Logger) LoggerFactory.getLogger("org.springframework.context"); + logger.setLevel(Level.INFO); + logger.addAppender(memoryAppender); + memoryAppender.start(); + } + + @Test + public void givenAutowireInBeanPostProcessor_whenSpringContextInitialize_thenNotEligibleLogShouldShowAndGroupFieldPopulated() { + List notEligibleEvents = memoryAppender.search("Bean 'randomIntGenerator' of type [com.baeldung.autoproxying.RandomIntGenerator] " + + "is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)"); + + assertEquals(0, notEligibleEvents.size()); + assertNotEquals(0, dataCache.getGroup()); + } +} diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java new file mode 100644 index 0000000000..fad35a7c2b --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java @@ -0,0 +1,48 @@ +package com.baeldung.component.autoproxying; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class MemoryLogAppender extends ListAppender { + public void reset() { + this.list.clear(); + } + + public boolean contains(String string, Level level) { + return this.list.stream() + .anyMatch(event -> event.getMessage().toString().contains(string) + && event.getLevel().equals(level)); + } + + public int countEventsForLogger(String loggerName) { + return (int) this.list.stream() + .filter(event -> event.getLoggerName().contains(loggerName)) + .count(); + } + + public List search(String string) { + return this.list.stream() + .filter(event -> event.getMessage().toString().contains(string)) + .collect(Collectors.toList()); + } + + public List search(String string, Level level) { + return this.list.stream() + .filter(event -> event.getMessage().toString().contains(string) + && event.getLevel().equals(level)) + .collect(Collectors.toList()); + } + + public int getSize() { + return this.list.size(); + } + + public List getLoggedEvents() { + return Collections.unmodifiableList(this.list); + } +} diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java new file mode 100644 index 0000000000..9434f77a30 --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java @@ -0,0 +1,48 @@ +package com.baeldung.component.autoproxying; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.ILoggingEvent; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {NotEligibleForAutoProxyRandomIntProcessor.class, DataCache.class, RandomIntGenerator.class}) +public class NotEligibleForAutoProxyingIntegrationTest { + private static MemoryLogAppender memoryAppender; + + private NotEligibleForAutoProxyRandomIntProcessor proxyRandomIntProcessor; + + @Autowired + private DataCache dataCache; + + @BeforeClass + public static void setup() { + memoryAppender = new MemoryLogAppender(); + memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); + + Logger logger = (Logger) LoggerFactory.getLogger("org.springframework.context"); + logger.setLevel(Level.INFO); + logger.addAppender(memoryAppender); + memoryAppender.start(); + } + + @Test + public void givenAutowireInBeanPostProcessor_whenSpringContextInitialize_thenNotEligibleLogShouldShowAndGroupFieldNotPopulated() { + List notEligibleEvents = memoryAppender.search("Bean 'randomIntGenerator' of type [com.baeldung.autoproxying.RandomIntGenerator] " + + "is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)"); + + assertEquals(1, notEligibleEvents.size()); + assertEquals(0, dataCache.getGroup()); + } +} diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index d7f875acd0..8f2bf31ee4 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -184,7 +184,6 @@ 5.10.2 5.13.1 2.21.0 - 1.8.5 2.8 8.2.1.Final diff --git a/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/DynamicSchedulingConfig.java b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/DynamicSchedulingConfig.java new file mode 100644 index 0000000000..b29f9ab0ce --- /dev/null +++ b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/DynamicSchedulingConfig.java @@ -0,0 +1,45 @@ +package com.baeldung.scheduling.dynamic; + +import java.time.Instant; +import java.util.Date; +import java.util.Optional; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; + +@Configuration +@ComponentScan("com.baeldung.scheduling.dynamic") +@EnableScheduling +public class DynamicSchedulingConfig implements SchedulingConfigurer { + + @Autowired + private TickService tickService; + + @Bean + public Executor taskExecutor() { + return Executors.newSingleThreadScheduledExecutor(); + } + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + taskRegistrar.setScheduler(taskExecutor()); + taskRegistrar.addTriggerTask( + () -> tickService.tick(), + context -> { + Optional lastCompletionTime = + Optional.ofNullable(context.lastCompletionTime()); + Instant nextExecutionTime = + lastCompletionTime.orElseGet(Date::new).toInstant() + .plusMillis(tickService.getDelay()); + return Date.from(nextExecutionTime); + } + ); + } + +} diff --git a/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/TickService.java b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/TickService.java new file mode 100644 index 0000000000..5da56f33a9 --- /dev/null +++ b/spring-scheduling/src/main/java/com/baeldung/scheduling/dynamic/TickService.java @@ -0,0 +1,22 @@ +package com.baeldung.scheduling.dynamic; + +import org.springframework.stereotype.Service; + +@Service +public class TickService { + + private long delay = 0; + + public long getDelay() { + this.delay += 1000; + System.out.println("delaying " + this.delay + " milliseconds..."); + return this.delay; + } + + public void tick() { + final long now = System.currentTimeMillis() / 1000; + System.out + .println("schedule tasks with dynamic delay - " + now); + } + +} diff --git a/spring-scheduling/src/test/java/com/baeldung/scheduling/DynamicSchedulingIntegrationTest.java b/spring-scheduling/src/test/java/com/baeldung/scheduling/DynamicSchedulingIntegrationTest.java new file mode 100644 index 0000000000..2ff9cfaefa --- /dev/null +++ b/spring-scheduling/src/test/java/com/baeldung/scheduling/DynamicSchedulingIntegrationTest.java @@ -0,0 +1,19 @@ +package com.baeldung.scheduling; + +import com.baeldung.scheduling.dynamic.DynamicSchedulingConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { + DynamicSchedulingConfig.class}, loader = AnnotationConfigContextLoader.class) +public class DynamicSchedulingIntegrationTest { + + @Test + public void testTickServiceTick() throws InterruptedException { + Thread.sleep(6000); + } +} diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index 99dea4bc67..096ffb9c3f 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -35,6 +35,7 @@ spring-security-legacy-oidc spring-security-oidc spring-security-okta + spring-security-saml spring-security-web-react spring-security-web-rest spring-security-web-rest-basic-auth diff --git a/spring-security-modules/spring-5-security/pom.xml b/spring-security-modules/spring-5-security/pom.xml index f50b5ff7a9..d009115c92 100644 --- a/spring-security-modules/spring-5-security/pom.xml +++ b/spring-security-modules/spring-5-security/pom.xml @@ -49,7 +49,7 @@ org.owasp.esapi esapi - 2.2.2.0 + ${esapi.version} org.jsoup 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/PersonControllerIntegrationTest.java similarity index 98% rename from spring-security-modules/spring-5-security/src/test/java/com/baeldung/xss/PersonControllerUnitTest.java rename to spring-security-modules/spring-5-security/src/test/java/com/baeldung/xss/PersonControllerIntegrationTest.java index 4e278ebf16..5afa3bc1dd 100644 --- 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/PersonControllerIntegrationTest.java @@ -14,7 +14,7 @@ import java.io.IOException; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class PersonControllerUnitTest { +class PersonControllerIntegrationTest { @LocalServerPort int randomServerPort; diff --git a/spring-security-modules/spring-security-saml/README.md b/spring-security-modules/spring-security-saml/README.md new file mode 100644 index 0000000000..271b29632e --- /dev/null +++ b/spring-security-modules/spring-security-saml/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [A Guide to SAML with Spring Security](https://www.baeldung.com/spring-security-saml) diff --git a/spring-security-modules/spring-security-saml/pom.xml b/spring-security-modules/spring-security-saml/pom.xml new file mode 100644 index 0000000000..561582045a --- /dev/null +++ b/spring-security-modules/spring-security-saml/pom.xml @@ -0,0 +1,73 @@ + + + 4.0.0 + spring-security-saml + 1.0-SNAPSHOT + spring-security-saml + war + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + Shibboleth + Shibboleth + https://build.shibboleth.net/nexus/content/repositories/releases/ + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.security.extensions + spring-security-saml2-core + ${saml2-core.spring.version} + + + + + spring-security-saml + + + src/main/resources + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + repackage + + + + + + + + + 1.0.10.RELEASE + + diff --git a/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/Application.java b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/Application.java new file mode 100644 index 0000000000..39eaa46424 --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/Application.java @@ -0,0 +1,11 @@ +package com.baeldung.saml; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + public static void main(String... args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/authentication/CustomSAMLAuthenticationProvider.java b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/authentication/CustomSAMLAuthenticationProvider.java new file mode 100644 index 0000000000..b35a72763d --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/authentication/CustomSAMLAuthenticationProvider.java @@ -0,0 +1,28 @@ +package com.baeldung.saml.authentication; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.providers.ExpiringUsernameAuthenticationToken; +import org.springframework.security.saml.SAMLAuthenticationProvider; +import org.springframework.security.saml.SAMLCredential; + +public class CustomSAMLAuthenticationProvider extends SAMLAuthenticationProvider { + + @Override + public Collection getEntitlements(SAMLCredential credential, Object userDetail) { + + if(userDetail instanceof ExpiringUsernameAuthenticationToken) { + List authorities = new ArrayList(); + authorities.addAll(((ExpiringUsernameAuthenticationToken) userDetail).getAuthorities()); + return authorities; + + } else { + return Collections.emptyList(); + } + } + +} diff --git a/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/config/SamlSecurityConfig.java b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/config/SamlSecurityConfig.java new file mode 100644 index 0000000000..378db478cf --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/config/SamlSecurityConfig.java @@ -0,0 +1,226 @@ +package com.baeldung.saml.config; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider; +import org.opensaml.saml2.metadata.provider.MetadataProvider; +import org.opensaml.saml2.metadata.provider.MetadataProviderException; +import org.opensaml.util.resource.ResourceException; +import org.opensaml.xml.parse.StaticBasicParserPool; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.security.saml.*; +import org.springframework.security.saml.context.SAMLContextProviderImpl; +import org.springframework.security.saml.key.JKSKeyManager; +import org.springframework.security.saml.key.KeyManager; +import org.springframework.security.saml.log.SAMLDefaultLogger; +import org.springframework.security.saml.metadata.CachingMetadataManager; +import org.springframework.security.saml.metadata.ExtendedMetadata; +import org.springframework.security.saml.metadata.ExtendedMetadataDelegate; +import org.springframework.security.saml.processor.*; +import org.springframework.security.saml.util.VelocityFactory; +import org.springframework.security.saml.websso.*; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.logout.LogoutHandler; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; + +import com.baeldung.saml.authentication.CustomSAMLAuthenticationProvider; + +@Configuration +public class SamlSecurityConfig { + + @Value("${saml.keystore.location}") + private String samlKeystoreLocation; + + @Value("${saml.keystore.password}") + private String samlKeystorePassword; + + @Value("${saml.keystore.alias}") + private String samlKeystoreAlias; + + @Value("${saml.idp}") + private String defaultIdp; + + @Bean(initMethod = "initialize") + public StaticBasicParserPool parserPool() { + return new StaticBasicParserPool(); + } + + @Bean + public SAMLAuthenticationProvider samlAuthenticationProvider() { + return new CustomSAMLAuthenticationProvider(); + } + + @Bean + public SAMLContextProviderImpl contextProvider() { + return new SAMLContextProviderImpl(); + } + + @Bean + public static SAMLBootstrap samlBootstrap() { + return new SAMLBootstrap(); + } + + @Bean + public SAMLDefaultLogger samlLogger() { + return new SAMLDefaultLogger(); + } + + @Bean + public WebSSOProfileConsumer webSSOprofileConsumer() { + return new WebSSOProfileConsumerImpl(); + } + + @Bean + @Qualifier("hokWebSSOprofileConsumer") + public WebSSOProfileConsumerHoKImpl hokWebSSOProfileConsumer() { + return new WebSSOProfileConsumerHoKImpl(); + } + + @Bean + public WebSSOProfile webSSOprofile() { + return new WebSSOProfileImpl(); + } + + @Bean + public WebSSOProfileConsumerHoKImpl hokWebSSOProfile() { + return new WebSSOProfileConsumerHoKImpl(); + } + + @Bean + public WebSSOProfileECPImpl ecpProfile() { + return new WebSSOProfileECPImpl(); + } + + @Bean + public SingleLogoutProfile logoutProfile() { + return new SingleLogoutProfileImpl(); + } + + @Bean + public KeyManager keyManager() { + DefaultResourceLoader loader = new DefaultResourceLoader(); + Resource storeFile = loader.getResource(samlKeystoreLocation); + Map passwords = new HashMap<>(); + passwords.put(samlKeystoreAlias, samlKeystorePassword); + return new JKSKeyManager(storeFile, samlKeystorePassword, passwords, samlKeystoreAlias); + } + + @Bean + public WebSSOProfileOptions defaultWebSSOProfileOptions() { + WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions(); + webSSOProfileOptions.setIncludeScoping(false); + return webSSOProfileOptions; + } + + @Bean + public SAMLEntryPoint samlEntryPoint() { + SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint(); + samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions()); + return samlEntryPoint; + } + + @Bean + public ExtendedMetadata extendedMetadata() { + ExtendedMetadata extendedMetadata = new ExtendedMetadata(); + extendedMetadata.setIdpDiscoveryEnabled(false); + extendedMetadata.setSignMetadata(false); + return extendedMetadata; + } + + @Bean + @Qualifier("okta") + public ExtendedMetadataDelegate oktaExtendedMetadataProvider() throws MetadataProviderException { + File metadata = null; + try { + metadata = new File("./src/main/resources/saml/metadata/sso.xml"); + } catch (Exception e) { + e.printStackTrace(); + } + FilesystemMetadataProvider provider = new FilesystemMetadataProvider(metadata); + provider.setParserPool(parserPool()); + return new ExtendedMetadataDelegate(provider, extendedMetadata()); + } + + @Bean + @Qualifier("metadata") + public CachingMetadataManager metadata() throws MetadataProviderException, ResourceException { + List providers = new ArrayList<>(); + providers.add(oktaExtendedMetadataProvider()); + CachingMetadataManager metadataManager = new CachingMetadataManager(providers); + metadataManager.setDefaultIDP(defaultIdp); + return metadataManager; + } + + @Bean + @Qualifier("saml") + public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() { + SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler = new SavedRequestAwareAuthenticationSuccessHandler(); + successRedirectHandler.setDefaultTargetUrl("/home"); + return successRedirectHandler; + } + + @Bean + @Qualifier("saml") + public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() { + SimpleUrlAuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler(); + failureHandler.setUseForward(true); + failureHandler.setDefaultFailureUrl("/error"); + return failureHandler; + } + + @Bean + public SimpleUrlLogoutSuccessHandler successLogoutHandler() { + SimpleUrlLogoutSuccessHandler successLogoutHandler = new SimpleUrlLogoutSuccessHandler(); + successLogoutHandler.setDefaultTargetUrl("/"); + return successLogoutHandler; + } + + @Bean + public SecurityContextLogoutHandler logoutHandler() { + SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler(); + logoutHandler.setInvalidateHttpSession(true); + logoutHandler.setClearAuthentication(true); + return logoutHandler; + } + + @Bean + public SAMLLogoutProcessingFilter samlLogoutProcessingFilter() { + return new SAMLLogoutProcessingFilter(successLogoutHandler(), logoutHandler()); + } + + @Bean + public SAMLLogoutFilter samlLogoutFilter() { + return new SAMLLogoutFilter(successLogoutHandler(), + new LogoutHandler[] { logoutHandler() }, + new LogoutHandler[] { logoutHandler() }); + } + + @Bean + public HTTPPostBinding httpPostBinding() { + return new HTTPPostBinding(parserPool(), VelocityFactory.getEngine()); + } + + @Bean + public HTTPRedirectDeflateBinding httpRedirectDeflateBinding() { + return new HTTPRedirectDeflateBinding(parserPool()); + } + + @Bean + public SAMLProcessorImpl processor() { + ArrayList bindings = new ArrayList<>(); + bindings.add(httpRedirectDeflateBinding()); + bindings.add(httpPostBinding()); + return new SAMLProcessorImpl(bindings); + } +} diff --git a/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/config/WebSecurityConfig.java b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/config/WebSecurityConfig.java new file mode 100644 index 0000000000..297c391823 --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/config/WebSecurityConfig.java @@ -0,0 +1,152 @@ +package com.baeldung.saml.config; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.saml.*; +import org.springframework.security.saml.key.KeyManager; +import org.springframework.security.saml.metadata.*; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.channel.ChannelProcessingFilter; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.csrf.CsrfFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled = true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${saml.sp}") + private String samlAudience; + + @Autowired + @Qualifier("saml") + private SavedRequestAwareAuthenticationSuccessHandler samlAuthSuccessHandler; + + @Autowired + @Qualifier("saml") + private SimpleUrlAuthenticationFailureHandler samlAuthFailureHandler; + + @Autowired + private SAMLEntryPoint samlEntryPoint; + + @Autowired + private SAMLLogoutFilter samlLogoutFilter; + + @Autowired + private SAMLLogoutProcessingFilter samlLogoutProcessingFilter; + + @Bean + public SAMLDiscovery samlDiscovery() { + SAMLDiscovery idpDiscovery = new SAMLDiscovery(); + return idpDiscovery; + } + + @Autowired + private SAMLAuthenticationProvider samlAuthenticationProvider; + + @Autowired + private ExtendedMetadata extendedMetadata; + + @Autowired + private KeyManager keyManager; + + public MetadataGenerator metadataGenerator() { + MetadataGenerator metadataGenerator = new MetadataGenerator(); + metadataGenerator.setEntityId(samlAudience); + metadataGenerator.setExtendedMetadata(extendedMetadata); + metadataGenerator.setIncludeDiscoveryExtension(false); + metadataGenerator.setKeyManager(keyManager); + return metadataGenerator; + } + + @Bean + public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception { + SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter(); + samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager()); + samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(samlAuthSuccessHandler); + samlWebSSOProcessingFilter.setAuthenticationFailureHandler(samlAuthFailureHandler); + return samlWebSSOProcessingFilter; + } + + @Bean + public FilterChainProxy samlFilter() throws Exception { + List chains = new ArrayList<>(); + chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"), + samlWebSSOProcessingFilter())); + chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/discovery/**"), + samlDiscovery())); + chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"), + samlEntryPoint)); + chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/logout/**"), + samlLogoutFilter)); + chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"), + samlLogoutProcessingFilter)); + return new FilterChainProxy(chains); + } + + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Bean + public MetadataGeneratorFilter metadataGeneratorFilter() { + return new MetadataGeneratorFilter(metadataGenerator()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .csrf() + .disable(); + + http + .httpBasic() + .authenticationEntryPoint(samlEntryPoint); + + http + .addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class) + .addFilterAfter(samlFilter(), BasicAuthenticationFilter.class) + .addFilterBefore(samlFilter(), CsrfFilter.class); + + http + .authorizeRequests() + .antMatchers("/").permitAll() + .anyRequest().authenticated(); + + http + .logout() + .addLogoutHandler((request, response, authentication) -> { + try { + response.sendRedirect("/saml/logout"); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(samlAuthenticationProvider); + } + +} diff --git a/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/controller/HomeController.java b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/controller/HomeController.java new file mode 100644 index 0000000000..e77933b8f3 --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/java/com/baeldung/saml/controller/HomeController.java @@ -0,0 +1,35 @@ +package com.baeldung.saml.controller; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class HomeController { + + @RequestMapping("/") + public String index() { + return "index"; + } + + @GetMapping(value = "/auth") + public String handleSamlAuth() { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null) { + return "redirect:/home"; + } else { + return "/"; + } + } + + @RequestMapping("/home") + public String home(Model model) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + model.addAttribute("username", authentication.getPrincipal()); + return "home"; + } + +} diff --git a/spring-security-modules/spring-security-saml/src/main/resources/application.properties b/spring-security-modules/spring-security-saml/src/main/resources/application.properties new file mode 100644 index 0000000000..f9d6a5df3c --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/resources/application.properties @@ -0,0 +1,6 @@ +saml.keystore.location=classpath:/saml/samlKeystore.jks +saml.keystore.password= +saml.keystore.alias= + +saml.idp= +saml.sp=http://localhost:8080/saml/metadata \ No newline at end of file diff --git a/spring-security-modules/spring-security-saml/src/main/resources/saml/metadata/sso.xml b/spring-security-modules/spring-security-saml/src/main/resources/saml/metadata/sso.xml new file mode 100644 index 0000000000..2d3258de12 --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/resources/saml/metadata/sso.xml @@ -0,0 +1,44 @@ + + + + + + + MIIDpDCCAoygAwIBAgIGAXGiSQ7ZMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYDVQQGEwJVUzETMBEG + A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU + MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi05MjY2NjYxHDAaBgkqhkiG9w0BCQEW + DWluZm9Ab2t0YS5jb20wHhcNMjAwNDIyMTQyNjA5WhcNMzAwNDIyMTQyNzA5WjCBkjELMAkGA1UE + BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV + BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtOTI2NjY2MRwwGgYJ + KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA + g1rQYYqeVx2gl/UUnLJzp5hrm06VOILJB9hIUmNqXgWV3UjzDq/zX0KW8MENjsO7+S8a+LLnYRkb + N5egH9FSt8AHtB1pmfXDtpUQmWe9yJbNxbCISoc6XzCmaRw3HRv9pK5SciIutciz9lvFaHMWAWtP + MmQSKdhMet52tuf6sTy4ODeXjyMnD9q5QOKww1SJ678wjHbGRRhNvCxvTSAH33sa4oNCf2RvP9hp + NiJRcYW9yLZXmZArPQOuAx5PIXfHhK2e4ac39YO4fgO7gwU5TZ+vL7o6iEmd9tk44PrND0ZV5yzZ + +Y33Hiun3fIiZu/nZZGUjm4k4exl8JJpwrVTHQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBcfHcL + 2DjTjZGoANF4dPpGXTYdVnL/XzGiLS+3LR/HDrEz/EqsHouF40RnzdZ7Ax7RReKBYCUUqHpSE+LU + ductz2ANguzyseGEn72I4Ym4ytQWnFyTXeW+xI9CoCLGfOUhT1hlKjsu/qNM8qwKFPWkzQp7mDN8 + S9MGhsnbiyeD/lceAEKw16Os73/sX2j7F+43WVCYRDCRB8pRIPfcqYLXUIUSstQlwEvCF7HyeO4+ + jxKHA1tp9Cpmj7/VD9TE3fyvrbVmfjTbKjF7/0wYQNfbHDDko0ratDMAizG5/d3i9wk9KbGCHSxT + ph5nl1pdjKgAYPK0iNDnGCZbGKzXOrqV + + + + + urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-saml/src/main/resources/saml/samlKeystore.jks b/spring-security-modules/spring-security-saml/src/main/resources/saml/samlKeystore.jks new file mode 100644 index 0000000000..7f3a5850d9 Binary files /dev/null and b/spring-security-modules/spring-security-saml/src/main/resources/saml/samlKeystore.jks differ diff --git a/spring-security-modules/spring-security-saml/src/main/resources/templates/error.html b/spring-security-modules/spring-security-saml/src/main/resources/templates/error.html new file mode 100644 index 0000000000..7223ee43fd --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/resources/templates/error.html @@ -0,0 +1,13 @@ + + + +
Something went wrong
+
+ +

+ An error occurred +

+
+ + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-saml/src/main/resources/templates/home.html b/spring-security-modules/spring-security-saml/src/main/resources/templates/home.html new file mode 100644 index 0000000000..c66e92c1f0 --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/resources/templates/home.html @@ -0,0 +1,13 @@ + + + +Baeldung Spring Security SAML: Home + + +

Welcome!
You are successfully logged in!

+

You are logged as null.

+ + Logout + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-saml/src/main/resources/templates/index.html b/spring-security-modules/spring-security-saml/src/main/resources/templates/index.html new file mode 100644 index 0000000000..7999c2fded --- /dev/null +++ b/spring-security-modules/spring-security-saml/src/main/resources/templates/index.html @@ -0,0 +1,10 @@ + + + +Baeldung Spring Security SAML + + +

Welcome to Baeldung Spring Security SAML

+ Login + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-angular/server/pom.xml b/spring-security-modules/spring-security-web-angular/server/pom.xml index 19d980062c..07d5d44e8d 100644 --- a/spring-security-modules/spring-security-web-angular/server/pom.xml +++ b/spring-security-modules/spring-security-web-angular/server/pom.xml @@ -62,9 +62,4 @@ - - UTF-8 - UTF-8 - - diff --git a/spring-web-modules/spring-mvc-basics-2/pom.xml b/spring-web-modules/spring-mvc-basics-2/pom.xml index 0b4515994b..adc42d8db8 100644 --- a/spring-web-modules/spring-mvc-basics-2/pom.xml +++ b/spring-web-modules/spring-mvc-basics-2/pom.xml @@ -131,14 +131,6 @@ json ${json.version}
- - org.apache.maven.surefire - surefire-logger-api - ${maven-surefire-plugin.version} - - test - true - @@ -163,7 +155,6 @@ 1.8 1.8 - 2.21.0 2.3.2-b02 4.0.0 6.0.10.Final diff --git a/spring-web-modules/spring-mvc-basics/src/main/resources/application.properties b/spring-web-modules/spring-mvc-basics/src/main/resources/application.properties index cf26fbfb60..b8a9be0b40 100644 --- a/spring-web-modules/spring-mvc-basics/src/main/resources/application.properties +++ b/spring-web-modules/spring-mvc-basics/src/main/resources/application.properties @@ -5,6 +5,3 @@ spring.mvc.pathmatch.use-suffix-pattern=true #spring.mvc.contentnegotiation.favor-path-extension=true #spring.mvc.contentnegotiation.favor-parameter=true #spring.mvc.contentnegotiation.parameter-name=mediaType - -# https://github.com/spring-projects/spring-boot/issues/24207 -spring.main.allow-bean-definition-overriding=true diff --git a/spring-web-modules/spring-mvc-java-2/README.md b/spring-web-modules/spring-mvc-java-2/README.md index 41ff7bdf7c..74d8cca312 100644 --- a/spring-web-modules/spring-mvc-java-2/README.md +++ b/spring-web-modules/spring-mvc-java-2/README.md @@ -6,4 +6,4 @@ - [A Quick Guide to Spring MVC Matrix Variables](https://www.baeldung.com/spring-mvc-matrix-variables) - [Converting a Spring MultipartFile to a File](https://www.baeldung.com/spring-multipartfile-to-file) - [Testing a Spring Multipart POST Request](https://www.baeldung.com/spring-multipart-post-request-test) -- [Spring @Pathvariable Annotation](https://www.baeldung.com/spring-pathvariable) +- [Spring @PathVariable Annotation](https://www.baeldung.com/spring-pathvariable) diff --git a/spring-web-modules/spring-mvc-views/pom.xml b/spring-web-modules/spring-mvc-views/pom.xml index 2c3be5a33e..649814263c 100644 --- a/spring-web-modules/spring-mvc-views/pom.xml +++ b/spring-web-modules/spring-mvc-views/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-spring-5 0.0.1-SNAPSHOT - parent-spring-5/pom.xml + ../../parent-spring-5 @@ -111,7 +111,6 @@ - 1.8 2.3.3 4.0.1 5.2.1.RELEASE diff --git a/spring-web-modules/spring-rest-http-2/pom.xml b/spring-web-modules/spring-rest-http-2/pom.xml index 6aa8be365c..a349ac1116 100644 --- a/spring-web-modules/spring-rest-http-2/pom.xml +++ b/spring-web-modules/spring-rest-http-2/pom.xml @@ -19,6 +19,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-webflux + io.springfox springfox-swagger2 @@ -29,10 +33,24 @@ springfox-swagger-ui ${swagger2.version} + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-data-jpa + + + io.github.resilience4j + resilience4j-timelimiter + ${resilience4j.version} + 2.9.2 + 1.6.1 diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/RequestTimeoutRestController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/RequestTimeoutRestController.java new file mode 100644 index 0000000000..d425737bab --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/RequestTimeoutRestController.java @@ -0,0 +1,61 @@ +package com.baeldung.requesttimeout; + +import com.baeldung.requesttimeout.domain.Book; +import com.baeldung.requesttimeout.domain.BookRepository; +import io.github.resilience4j.timelimiter.TimeLimiter; +import io.github.resilience4j.timelimiter.TimeLimiterConfig; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.reactive.function.client.WebClient; + +import java.time.Duration; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; + +@RestController +public class RequestTimeoutRestController { + + private final BookRepository bookRepository; + private final WebClient webClient; + + public RequestTimeoutRestController(BookRepository bookRepository, WebClient webClient) { + this.bookRepository = bookRepository; + this.webClient = webClient; + } + + @GetMapping("/author/transactional") + @Transactional(timeout = 1) + public String getWithTransactionTimeout(@RequestParam String title) { + return getAuthor(title); + } + + private final TimeLimiter ourTimeLimiter = TimeLimiter.of(TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(500)).build()); + @GetMapping("/author/resilience4j") + public Callable getWithResilience4jTimeLimiter(@RequestParam String title) { + return TimeLimiter.decorateFutureSupplier(ourTimeLimiter, () -> CompletableFuture.supplyAsync(() -> getAuthor(title))); + } + + @GetMapping("/author/mvc-request-timeout") + public Callable getWithMvcRequestTimeout(@RequestParam String title) { + return () -> getAuthor(title); + } + + @GetMapping("/author/webclient") + public String getWithWebClient(@RequestParam String title) { + return webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/author/transactional") + .queryParam("title", title) + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + } + + private String getAuthor(String title) { + bookRepository.wasteTime(); + return bookRepository.findById(title).map(Book::getAuthor).orElse("No book found for this title."); + } +} diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/configuration/WebClientConfiguration.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/configuration/WebClientConfiguration.java new file mode 100644 index 0000000000..52b3573411 --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/configuration/WebClientConfiguration.java @@ -0,0 +1,21 @@ +package com.baeldung.requesttimeout.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.netty.http.client.HttpClient; + +import java.time.Duration; + +@Configuration +public class WebClientConfiguration { + + @Bean + public WebClient webClient() { + return WebClient.builder() + .baseUrl("http://localhost:8080") + .clientConnector(new ReactorClientHttpConnector(HttpClient.create().responseTimeout(Duration.ofMillis(250)))) + .build(); + } +} diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/domain/Book.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/domain/Book.java new file mode 100644 index 0000000000..846bfb2cec --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/domain/Book.java @@ -0,0 +1,28 @@ +package com.baeldung.requesttimeout.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Book { + + @Id + private String title; + private String author; + + public void setTitle(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/domain/BookRepository.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/domain/BookRepository.java new file mode 100644 index 0000000000..8ecab0f1d2 --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/requesttimeout/domain/BookRepository.java @@ -0,0 +1,14 @@ +package com.baeldung.requesttimeout.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BookRepository extends JpaRepository { + + default int wasteTime() { + int i = Integer.MIN_VALUE; + while(i < Integer.MAX_VALUE) { + i++; + } + return i; + } +} diff --git a/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties b/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties new file mode 100644 index 0000000000..ff4af943ec --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.mvc.async.request-timeout=750 \ No newline at end of file diff --git a/spring-web-modules/spring-rest-http-2/src/test/com/baeldung/requesttimeout/RequestTimeoutUnitTest.java b/spring-web-modules/spring-rest-http-2/src/test/com/baeldung/requesttimeout/RequestTimeoutUnitTest.java new file mode 100644 index 0000000000..da7d40d53c --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/test/com/baeldung/requesttimeout/RequestTimeoutUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.requesttimeout; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClientRequestException; + +@SpringBootTest +@RunWith(SpringRunner.class) +public class RequestTimeoutTests { + + private static final WebClient WEB_CLIENT = WebClient.builder().baseUrl("http://localhost:8080").build(); + + @Test(expected = WebClientRequestException.class) + public void givenTransactionTimeout_whenTimeExpires_thenReceiveException() { + getAuthor("transactional"); + } + + @Test(expected = WebClientRequestException.class) + public void givenResilience4jTimeLimiter_whenTimeExpires_thenReceiveException() { + getAuthor("resilience4j"); + } + + @Test(expected = WebClientRequestException.class) + public void givenMvcRequestTimeout_whenTimeExpires_thenReceiveException() { + getAuthor("mvc-request-timeout"); + } + + @Test(expected = WebClientRequestException.class) + public void givenWebClientTimeout_whenTimeExpires_thenReceiveException() { + getAuthor("webclient"); + } + + private void getAuthor(String authorPath) { + WEB_CLIENT.get() + .uri(uriBuilder -> uriBuilder + .path("/author/" + authorPath) + .queryParam("title", "title") + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + } +} diff --git a/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties b/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties new file mode 100644 index 0000000000..ff4af943ec --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties @@ -0,0 +1 @@ +spring.mvc.async.request-timeout=750 \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index 4756223c3d..f53af9347f 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -35,18 +35,8 @@ - - - - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - 5.4.2 - 2.21.0 5.4.2 diff --git a/testing-modules/junit-5-basics/pom.xml b/testing-modules/junit-5-basics/pom.xml index b9c9635dc4..cdb0c367ce 100644 --- a/testing-modules/junit-5-basics/pom.xml +++ b/testing-modules/junit-5-basics/pom.xml @@ -152,7 +152,6 @@ 1.2.0 5.4.2 5.0.6.RELEASE - 2.21.0 diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 831fa97e12..ded3e9e26d 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -105,10 +105,6 @@ - - maven-surefire-plugin - ${maven-surefire-plugin.version} - org.codehaus.mojo exec-maven-plugin diff --git a/testing-modules/junit5-migration/pom.xml b/testing-modules/junit5-migration/pom.xml index 3b2663d81d..e3ef21f506 100644 --- a/testing-modules/junit5-migration/pom.xml +++ b/testing-modules/junit5-migration/pom.xml @@ -18,12 +18,12 @@ org.junit.platform junit-platform-engine - ${junit.platform.version} + ${junit-platform.version} org.junit.platform junit-platform-runner - ${junit.platform.version} + ${junit-platform.version} test @@ -48,17 +48,6 @@ - - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - - - org.codehaus.mojo exec-maven-plugin @@ -79,7 +68,7 @@ 5.2.0 - 1.2.0 + 1.2.0 5.2.0 2.21.0 1.6.0 diff --git a/testing-modules/mockito-3/.gitignore b/testing-modules/mockito-3/.gitignore new file mode 100644 index 0000000000..38fe5148c1 --- /dev/null +++ b/testing-modules/mockito-3/.gitignore @@ -0,0 +1,4 @@ +/target/ +/.settings/ +/.classpath +/.project \ No newline at end of file diff --git a/testing-modules/mockito-3/pom.xml b/testing-modules/mockito-3/pom.xml new file mode 100644 index 0000000000..8d506561ed --- /dev/null +++ b/testing-modules/mockito-3/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + mockito-3 + 0.0.1-SNAPSHOT + mockito-3 + jar + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + org.mockito + mockito-inline + ${mockito.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + 3.8.0 + 3.8.0 + + + diff --git a/testing-modules/mockito-3/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java b/testing-modules/mockito-3/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java new file mode 100644 index 0000000000..2e2f5ead33 --- /dev/null +++ b/testing-modules/mockito-3/src/main/java/com/baeldung/mockito/mockedstatic/StaticUtils.java @@ -0,0 +1,22 @@ +package com.baeldung.mockito.mockedstatic; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class StaticUtils { + + private StaticUtils() { + } + + public static List range(int start, int end) { + return IntStream.range(start, end) + .boxed() + .collect(Collectors.toList()); + } + + public static String name() { + return "Baeldung"; + } + +} diff --git a/testing-modules/mockito-3/src/main/resources/logback.xml b/testing-modules/mockito-3/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/mockito-3/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/mockito-3/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java b/testing-modules/mockito-3/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java new file mode 100644 index 0000000000..a212e6e3eb --- /dev/null +++ b/testing-modules/mockito-3/src/test/java/com/baeldung/mockito/mockedstatic/MockedStaticUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.mockito.mockedstatic; + +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import static org.assertj.core.api.Assertions.*; + +import java.util.Arrays; + +class MockedStaticUnitTest { + + @Test + void givenStaticMethodWithNoArgs_whenMocked_thenReturnsMockSuccessfully() { + assertThat(StaticUtils.name()).isEqualTo("Baeldung"); + + try (MockedStatic utilities = Mockito.mockStatic(StaticUtils.class)) { + utilities.when(StaticUtils::name).thenReturn("Eugen"); + assertThat(StaticUtils.name()).isEqualTo("Eugen"); + } + + assertThat(StaticUtils.name()).isEqualTo("Baeldung"); + } + + @Test + void givenStaticMethodWithArgs_whenMocked_thenReturnsMockSuccessfully() { + assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5); + + try (MockedStatic utilities = Mockito.mockStatic(StaticUtils.class)) { + utilities.when(() -> StaticUtils.range(2, 6)) + .thenReturn(Arrays.asList(10, 11, 12)); + + assertThat(StaticUtils.range(2, 6)).containsExactly(10, 11, 12); + } + + assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5); + } + +} diff --git a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml index fb12803333..fdd45e19d6 100644 --- a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml +++ b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml @@ -27,7 +27,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.0 + ${maven-surefire-plugin.version} all 10 @@ -45,4 +45,8 @@ + + 2.22.0 + + diff --git a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml index 313d82c23f..727a1f814a 100644 --- a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml +++ b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml @@ -27,7 +27,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.0 + ${maven-surefire-plugin.version} all true @@ -37,4 +37,8 @@ + + 2.22.0 + + diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index fd4a13d026..c0c28e085d 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -23,7 +23,8 @@ junit5-migration load-testing-comparison mockito - mockito-2 + mockito-2 + mockito-3 hamcrest mocks mockserver diff --git a/testing-modules/spring-testing-2/pom.xml b/testing-modules/spring-testing-2/pom.xml index 4686a20202..40b556732a 100644 --- a/testing-modules/spring-testing-2/pom.xml +++ b/testing-modules/spring-testing-2/pom.xml @@ -73,6 +73,5 @@ 1.12.2 - 2.21.0 \ No newline at end of file diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml index 9e0c986bb2..74d55d4c08 100644 --- a/testing-modules/spring-testing/pom.xml +++ b/testing-modules/spring-testing/pom.xml @@ -125,7 +125,7 @@ 3.1.6 5.7.0 1.7.0 - 5.3.0 + 5.3.4 4.0.1 2.1.1
diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java index 9b692edd7b..9481c54b48 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java @@ -1,15 +1,14 @@ package com.baeldung.overrideproperties; import com.baeldung.overrideproperties.resolver.PropertySourceResolver; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; -@RunWith(SpringRunner.class) +@SpringBootTest @ContextConfiguration(initializers = PropertyOverrideContextInitializer.class, classes = Application.class) public class ContextPropertySourceResolverIntegrationTest { diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java index 815b628f0a..77b882d3a2 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java @@ -1,18 +1,17 @@ package com.baeldung.overrideproperties; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import com.baeldung.overrideproperties.resolver.PropertySourceResolver; -@RunWith(SpringRunner.class) +import static org.junit.jupiter.api.Assertions.assertEquals; + @SpringBootTest @ActiveProfiles("test") @EnableWebMvc diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java index a8c4267c5c..994a8a4288 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java @@ -12,6 +12,6 @@ public class PropertyOverrideContextInitializer implements ApplicationContextIni public void initialize(ConfigurableApplicationContext configurableApplicationContext) { TestPropertySourceUtils.addInlinedPropertiesToEnvironment(configurableApplicationContext, "example.firstProperty=" + PROPERTY_FIRST_VALUE); - TestPropertySourceUtils.addPropertiesFilesToEnvironment(configurableApplicationContext, "context-override-application.properties"); + TestPropertySourceUtils.addPropertiesFilesToEnvironment(configurableApplicationContext, "classpath:context-override-application.properties"); } } diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java index d00aa51e6c..bb08d701d9 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java @@ -1,16 +1,16 @@ package com.baeldung.overrideproperties; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import com.baeldung.overrideproperties.resolver.PropertySourceResolver; -@RunWith(SpringRunner.class) +import static org.junit.jupiter.api.Assertions.assertEquals; + @SpringBootTest(properties = { "example.firstProperty=annotation" }) @EnableWebMvc public class SpringBootPropertySourceResolverIntegrationTest { @@ -23,8 +23,8 @@ public class SpringBootPropertySourceResolverIntegrationTest { final String firstProperty = propertySourceResolver.getFirstProperty(); final String secondProperty = propertySourceResolver.getSecondProperty(); - Assert.assertEquals("annotation", firstProperty); - Assert.assertEquals("file", secondProperty); + assertEquals("annotation", firstProperty); + assertEquals("file", secondProperty); } } \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java index dc15851277..673742124a 100644 --- a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java @@ -1,17 +1,16 @@ package com.baeldung.overrideproperties; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import com.baeldung.overrideproperties.resolver.PropertySourceResolver; -@RunWith(SpringRunner.class) +import static org.junit.jupiter.api.Assertions.assertEquals; + @SpringBootTest @EnableWebMvc public class TestResourcePropertySourceResolverIntegrationTest { diff --git a/testing-modules/test-containers/pom.xml b/testing-modules/test-containers/pom.xml index e83d3aff32..1946b7306f 100644 --- a/testing-modules/test-containers/pom.xml +++ b/testing-modules/test-containers/pom.xml @@ -80,17 +80,6 @@ - - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform-surefire-provider.version} - - - org.codehaus.mojo exec-maven-plugin @@ -117,7 +106,7 @@ 42.2.6 3.141.59 2.22.2 - 1.3.2 + 1.3.2
diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index fa0f666c7f..8b8536462d 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -16,47 +16,43 @@ ch.qos.logback logback-classic - 1.2.3 + ${logback.version} org.junit.jupiter junit-jupiter-engine - 5.6.2 + ${junit-jupiter.version} test org.junit.jupiter junit-jupiter-api - 5.6.2 + ${junit-jupiter.version} test org.assertj assertj-core - 3.16.1 + ${assertj-core.version} test org.hamcrest hamcrest-all - 1.3 + ${hamcrest-all.version} test org.apache.commons commons-collections4 - 4.4 + ${commons-collections4.version} test - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.1 - - - + + 3.16.1 + 4.4 + 5.6.2 + diff --git a/testing-modules/testing-libraries-2/pom.xml b/testing-modules/testing-libraries-2/pom.xml index 42c84d0da9..7f96280cac 100644 --- a/testing-modules/testing-libraries-2/pom.xml +++ b/testing-modules/testing-libraries-2/pom.xml @@ -16,7 +16,7 @@ org.assertj assertj-core - 3.16.1 + ${assertj-core.version} test @@ -86,5 +86,6 @@ 1.0.0 1.1.0 5.6.2 + 3.16.1 diff --git a/testing-modules/testing-libraries/pom.xml b/testing-modules/testing-libraries/pom.xml index aa22a5253e..4edd13fa30 100644 --- a/testing-modules/testing-libraries/pom.xml +++ b/testing-modules/testing-libraries/pom.xml @@ -36,11 +36,10 @@ ${cucumber.version} test - org.springframework.boot spring-boot-starter-web - 2.2.0.RELEASE + ${spring-boot.version} com.github.stefanbirkner @@ -103,6 +102,7 @@ 3.0.0 1.19.0 1.0.0 + 2.4.3 diff --git a/testing-modules/zerocode/README.md b/testing-modules/zerocode/README.md new file mode 100644 index 0000000000..a0a844c63d --- /dev/null +++ b/testing-modules/zerocode/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Introduction to ZeroCode](https://www.baeldung.com/zerocode-intro) diff --git a/testing-modules/zerocode/pom.xml b/testing-modules/zerocode/pom.xml index 9d765e6cb4..63f0dc9cbb 100644 --- a/testing-modules/zerocode/pom.xml +++ b/testing-modules/zerocode/pom.xml @@ -28,7 +28,7 @@ org.jsmart zerocode-tdd - 1.3.27 + ${zerocode-tdd.version} test @@ -68,7 +68,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.0.0-M5 + ${maven-failsafe-plugin.version} ${skip.it} @@ -76,7 +76,7 @@ org.apache.maven.surefire surefire-junit47 - 3.0.0-M5 + ${surefire-junit47.version} @@ -92,11 +92,13 @@ - UTF-8 + 3.0.0-M5 + 3.0.0-M5 8 8 2.4.2 true + 1.3.27 diff --git a/webrtc/pom.xml b/webrtc/pom.xml index f302ae97a2..191ff11dd6 100644 --- a/webrtc/pom.xml +++ b/webrtc/pom.xml @@ -31,8 +31,4 @@ - - 1.8 - - diff --git a/wildfly/pom.xml b/wildfly/pom.xml index 7b2a474c8d..6d823bb4c9 100644 --- a/wildfly/pom.xml +++ b/wildfly/pom.xml @@ -76,8 +76,4 @@ - - 1.8 - - diff --git a/xml/pom.xml b/xml/pom.xml index 837f918b46..d2fa5c0727 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -75,12 +75,12 @@ org.openjdk.jmh jmh-core - ${jmh.version} + ${jmh-core.version} org.openjdk.jmh jmh-generator-annprocess - ${jmh.version} + ${jmh-generator.version} @@ -322,8 +322,8 @@ org.apache.maven.plugins maven-compiler-plugin - ${java-version} - ${java-version} + ${java.version} + ${java.version} @@ -374,17 +374,14 @@ 3.12.2 2.6.3 5.5.0 - 1.21 2.3.29 0.9.6 2.4 - 1.8 1.3.1 3.8.0 - 2.22.2 diff --git a/xml/src/main/java/com/baeldung/sax/SaxParserMain.java b/xml/src/main/java/com/baeldung/sax/SaxParserMain.java index 4908c10386..34a46fe469 100644 --- a/xml/src/main/java/com/baeldung/sax/SaxParserMain.java +++ b/xml/src/main/java/com/baeldung/sax/SaxParserMain.java @@ -28,11 +28,15 @@ public class SaxParserMain { private static final String CONTENT = "content"; private Baeldung website; - private String elementValue; + private StringBuilder elementValue; @Override public void characters(char[] ch, int start, int length) throws SAXException { - elementValue = new String(ch, start, length); + if (elementValue == null) { + elementValue = new StringBuilder(); + } else { + elementValue.append(ch, start, length); + } } @Override @@ -48,6 +52,13 @@ public class SaxParserMain { break; case ARTICLE: website.getArticleList().add(new BaeldungArticle()); + break; + case TITLE: + elementValue = new StringBuilder(); + break; + case CONTENT: + elementValue = new StringBuilder(); + break; } } @@ -55,10 +66,10 @@ public class SaxParserMain { public void endElement(String uri, String localName, String qName) throws SAXException { switch (qName) { case TITLE: - latestArticle().setTitle(elementValue); + latestArticle().setTitle(elementValue.toString()); break; case CONTENT: - latestArticle().setContent(elementValue); + latestArticle().setContent(elementValue.toString()); break; } }