diff --git a/algorithms-miscellaneous-5/pom.xml b/algorithms-miscellaneous-5/pom.xml
index 4f9cc8b711..2799c39971 100644
--- a/algorithms-miscellaneous-5/pom.xml
+++ b/algorithms-miscellaneous-5/pom.xml
@@ -39,6 +39,16 @@
guava
${guava.version}
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+ org.junit.platform
+ junit-platform-commons
+ ${junit.platform.version}
+
org.assertj
@@ -66,6 +76,8 @@
1.11
3.6.1
28.1-jre
+ 2.10.2
+ 1.6.0
\ No newline at end of file
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java
new file mode 100644
index 0000000000..0f8bc5b296
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java
@@ -0,0 +1,61 @@
+package com.baeldung.algorithms.boruvka;
+
+public class BoruvkaMST {
+
+ private static Tree mst = new Tree();
+ private static int totalWeight;
+
+ public BoruvkaMST(Graph graph) {
+ DisjointSet dSet = new DisjointSet(graph.getNodes());
+
+ // repeat at most log N times or until we have N-1 edges
+ for (int t = 1; t < graph.getNodes() && mst.getEdgeCount() < graph.getNodes() - 1; t = t + t) {
+
+ // foreach tree in forest, find closest edge
+ Edge[] closestEdgeArray = new Edge[graph.getNodes()];
+ for (Edge edge : graph.getAllEdges()) {
+ int first = edge.getFirst();
+ int second = edge.getSecond();
+ int firstParent = dSet.getParent(first);
+ int secondParent = dSet.getParent(second);
+ if (firstParent == secondParent) {
+ continue; // same tree
+ }
+ if (closestEdgeArray[firstParent] == null || edge.getWeight() < closestEdgeArray[firstParent].getWeight()) {
+ closestEdgeArray[firstParent] = edge;
+ }
+ if (closestEdgeArray[secondParent] == null || edge.getWeight() < closestEdgeArray[secondParent].getWeight()) {
+ closestEdgeArray[secondParent] = edge;
+ }
+ }
+
+ // add newly discovered edges to MST
+ for (int i = 0; i < graph.getNodes(); i++) {
+ Edge edge = closestEdgeArray[i];
+ if (edge != null) {
+ int first = edge.getFirst();
+ int second = edge.getSecond();
+ // don't add the same edge twice
+ if (dSet.getParent(first) != dSet.getParent(second)) {
+ mst.addEdge(edge);
+ totalWeight += edge.getWeight();
+ dSet.union(first, second);
+ }
+ }
+ }
+ }
+ }
+
+ public Iterable getMST() {
+ return mst;
+ }
+
+ public int getTotalWeight() {
+ return totalWeight;
+ }
+
+ public String toString() {
+ return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
+ }
+
+}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/DisjointSet.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/DisjointSet.java
new file mode 100644
index 0000000000..7769686e36
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/DisjointSet.java
@@ -0,0 +1,49 @@
+package com.baeldung.algorithms.boruvka;
+
+import java.util.Arrays;
+
+public class DisjointSet {
+
+ private int[] nodeParents;
+ private int[] nodeRanks;
+
+ public DisjointSet(int n) {
+ nodeParents = new int[n];
+ nodeRanks = new int[n];
+ for (int i = 0; i < n; i++) {
+ nodeParents[i] = i;
+ nodeRanks[i] = 0;
+ }
+ }
+
+ public int getParent(int node) {
+ while (node != nodeParents[node]) {
+ node = nodeParents[node];
+ }
+ return node;
+ }
+
+ public void union(int node1, int node2) {
+ int node1Parent = getParent(node1);
+ int node2Parent = getParent(node2);
+ if (node1Parent == node2Parent) {
+ return;
+ }
+
+ if (nodeRanks[node1Parent] < nodeRanks[node2Parent]) {
+ nodeParents[node1Parent] = node2Parent;
+ }
+ else if (nodeRanks[node1Parent] > nodeRanks[node2Parent]) {
+ nodeParents[node2Parent] = node1Parent;
+ }
+ else {
+ nodeParents[node2Parent] = node1Parent;
+ nodeRanks[node1Parent]++;
+ }
+ }
+
+ public String toString() {
+ return "Parent: " + Arrays.toString(nodeParents) + "Rank: " + Arrays.toString(nodeRanks);
+ }
+
+}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Edge.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Edge.java
new file mode 100644
index 0000000000..6ee136fc48
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Edge.java
@@ -0,0 +1,40 @@
+package com.baeldung.algorithms.boruvka;
+
+public class Edge {
+
+ private final int first;
+ private final int second;
+ private final int weight;
+
+ public Edge(int first, int second, int weight) {
+ this.first = first;
+ this.second = second;
+ this.weight = weight;
+ }
+
+ public double getWeight() {
+ return weight;
+ }
+
+ public int getFirst() {
+ return first;
+ }
+
+ public int getSecond() {
+ return second;
+ }
+
+ public int getOtherNode(int firstNode) {
+ int secondNode = 0;
+ if (firstNode == first)
+ secondNode = second;
+ else if (firstNode == second)
+ secondNode = first;
+ return secondNode;
+ }
+
+ public String toString() {
+ return String.format("%d-%d %d", first, second, weight);
+ }
+
+}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Graph.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Graph.java
new file mode 100644
index 0000000000..e899007dfa
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Graph.java
@@ -0,0 +1,64 @@
+package com.baeldung.algorithms.boruvka;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+public class Graph {
+
+ private int nodes;
+ private int edges;
+ private Tree[] trees;
+
+ public Graph(Input jsonGraph) throws JsonParseException, JsonMappingException, IOException {
+ nodes = jsonGraph.getNodes();
+ trees = (Tree[]) new Tree[nodes];
+ for (int i = 0; i < nodes; i++) {
+ trees[i] = new Tree();
+ }
+
+ int edgesFromInput = jsonGraph.getEdges();
+ for (int i = 0; i < edgesFromInput; i++) {
+ int first = jsonGraph.getEdgeList()
+ .get(i)
+ .getFirst();
+ int second = jsonGraph.getEdgeList()
+ .get(i)
+ .getSecond();
+ int weight = jsonGraph.getEdgeList()
+ .get(i)
+ .getWeight();
+ Edge edge = new Edge(first, second, weight);
+
+ trees[first].addEdge(edge);
+ trees[second].addEdge(edge);
+ edges++;
+ }
+
+ }
+
+ public int getNodes() {
+ return nodes;
+ }
+
+ public int getEdges() {
+ return edges;
+ }
+
+ public Iterable iterableTree(int i) {
+ return trees[i];
+ }
+
+ public Iterable getAllEdges() {
+ Iterable list = new Tree();
+ for (int i = 0; i < nodes; i++) {
+ for (Edge edge : iterableTree(i)) {
+ if (edge.getOtherNode(i) > i) {
+ ((Tree) list).addEdge(edge);
+ }
+ }
+ }
+ return list;
+ }
+}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Input.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Input.java
new file mode 100644
index 0000000000..b52720d5e9
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Input.java
@@ -0,0 +1,65 @@
+package com.baeldung.algorithms.boruvka;
+
+import java.util.List;
+
+public class Input {
+ private int nodes;
+ private int edges;
+ private List edgeList;
+
+ public int getNodes() {
+ return nodes;
+ }
+
+ public void setNodes(int nodes) {
+ this.nodes = nodes;
+ }
+
+ public int getEdges() {
+ return edges;
+ }
+
+ public void setEdges(int edges) {
+ this.edges = edges;
+ }
+
+ public List getEdgeList() {
+ return edgeList;
+ }
+
+ public void setEdgeList(List edgeList) {
+ this.edgeList = edgeList;
+ }
+
+ static class E {
+ private int first;
+ private int second;
+ private int weight;
+
+ public int getFirst() {
+ return first;
+ }
+
+ public void setFirst(int first) {
+ this.first = first;
+ }
+
+ public int getSecond() {
+ return second;
+ }
+
+ public void setSecond(int second) {
+ this.second = second;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+
+ }
+
+}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Tree.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Tree.java
new file mode 100644
index 0000000000..cc28233e07
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Tree.java
@@ -0,0 +1,63 @@
+package com.baeldung.algorithms.boruvka;
+
+import java.util.Iterator;
+
+public class Tree implements Iterable {
+ private Node root;
+ private int edgeCount;
+
+ private static class Node {
+ private Edge edge;
+ private Node next;
+
+ public String toString() {
+ String nextStr = next != null ? next.toString() : "";
+ return edge.toString() + " | " + nextStr;
+ }
+ }
+
+ public Tree() {
+ root = null;
+ edgeCount = 0;
+ }
+
+ public int getEdgeCount() {
+ return edgeCount;
+ }
+
+ public void addEdge(Edge edge) {
+ Node oldRoot = root;
+ root = new Node();
+ root.edge = edge;
+ root.next = oldRoot;
+ edgeCount++;
+ }
+
+ public String toString() {
+ String rootStr = root != null ? root.toString() : "";
+ return "Tree: " + rootStr + "Size: " + edgeCount;
+ }
+
+ public Iterator iterator() {
+ return new LinkedIterator(root);
+ }
+
+ private class LinkedIterator implements Iterator {
+ private Node current;
+
+ public LinkedIterator(Node root) {
+ current = root;
+ }
+
+ public boolean hasNext() {
+ return current != null;
+ }
+
+ public Edge next() {
+ Edge edge = current.edge;
+ current = current.next;
+ return edge;
+ }
+ }
+
+}
diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java
new file mode 100644
index 0000000000..1d03d2d4d9
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java
@@ -0,0 +1,48 @@
+package com.baeldung.algorithms.boruvka;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class BoruvkaUnitTest {
+
+ private Input input;
+ private static String INPUT_JSON = "/input.json";
+
+ @Before
+ public void convertInputJsonToObject() throws JsonParseException, JsonMappingException, IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ StringBuilder jsonStr = new StringBuilder();
+ try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(BoruvkaMST.class.getResourceAsStream(INPUT_JSON)))) {
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ jsonStr.append(line)
+ .append("\n");
+ }
+ }
+
+ input = mapper.readValue(jsonStr.toString(), Input.class);
+
+ }
+
+ @Test
+ public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() throws JsonParseException, JsonMappingException, IOException {
+ Graph graph = new Graph(input);
+ BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
+
+ Tree mst = (Tree) boruvkaMST.getMST();
+
+ assertEquals(30, boruvkaMST.getTotalWeight());
+ assertEquals(4, mst.getEdgeCount());
+ }
+
+}
diff --git a/algorithms-miscellaneous-5/src/test/resources/input.json b/algorithms-miscellaneous-5/src/test/resources/input.json
new file mode 100644
index 0000000000..0151f83618
--- /dev/null
+++ b/algorithms-miscellaneous-5/src/test/resources/input.json
@@ -0,0 +1,41 @@
+{
+ "nodes": 5,
+ "edges": 7,
+ "edgeList": [
+ {
+ "first": 0,
+ "second": 1,
+ "weight": 8
+ },
+ {
+ "first": 0,
+ "second": 2,
+ "weight": 5
+ },
+ {
+ "first": 1,
+ "second": 2,
+ "weight": 9
+ },
+ {
+ "first": 1,
+ "second": 3,
+ "weight": 11
+ },
+ {
+ "first": 2,
+ "second": 3,
+ "weight": 15
+ },
+ {
+ "first": 2,
+ "second": 4,
+ "weight": 10
+ },
+ {
+ "first": 3,
+ "second": 4,
+ "weight": 7
+ }
+ ]
+}
\ No newline at end of file
diff --git a/apache-beam/pom.xml b/apache-beam/pom.xml
new file mode 100644
index 0000000000..7a714ac480
--- /dev/null
+++ b/apache-beam/pom.xml
@@ -0,0 +1,43 @@
+
+ 4.0.0
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+ com.baeldung.apache
+ apache-beam
+ 0.0.1-SNAPSHOT
+
+
+
+ org.apache.beam
+ beam-sdks-java-core
+ ${beam.version}
+
+
+
+ org.apache.beam
+ beam-runners-direct-java
+ ${beam.version}
+ runtime
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+ 2.19.0
+ 3.6.1
+
+
+
diff --git a/apache-beam/src/main/java/com/baeldung/apache/beam/intro/WordCount.java b/apache-beam/src/main/java/com/baeldung/apache/beam/intro/WordCount.java
new file mode 100644
index 0000000000..f2dfb47810
--- /dev/null
+++ b/apache-beam/src/main/java/com/baeldung/apache/beam/intro/WordCount.java
@@ -0,0 +1,71 @@
+package com.baeldung.apache.beam.intro;
+
+import java.util.Arrays;
+
+import org.apache.beam.sdk.Pipeline;
+import org.apache.beam.sdk.io.TextIO;
+import org.apache.beam.sdk.options.PipelineOptions;
+import org.apache.beam.sdk.options.PipelineOptionsFactory;
+import org.apache.beam.sdk.transforms.Count;
+import org.apache.beam.sdk.transforms.Filter;
+import org.apache.beam.sdk.transforms.FlatMapElements;
+import org.apache.beam.sdk.transforms.MapElements;
+import org.apache.beam.sdk.values.KV;
+import org.apache.beam.sdk.values.PCollection;
+import org.apache.beam.sdk.values.TypeDescriptors;
+
+public class WordCount {
+
+ public static boolean wordCount(String inputFilePath, String outputFilePath) {
+ // We use default options
+ PipelineOptions options = PipelineOptionsFactory.create();
+ // to create the pipeline
+ Pipeline p = Pipeline.create(options);
+ // Here is our workflow graph
+ PCollection> wordCount = p
+ .apply("(1) Read all lines", TextIO.read().from(inputFilePath))
+ .apply("(2) Flatmap to a list of words", FlatMapElements.into(TypeDescriptors.strings())
+ .via(line -> Arrays.asList(line.split("\\s"))))
+ .apply("(3) Lowercase all", MapElements.into(TypeDescriptors.strings())
+ .via(word -> word.toLowerCase()))
+ .apply("(4) Trim punctuations", MapElements.into(TypeDescriptors.strings())
+ .via(word -> trim(word)))
+ .apply("(5) Filter stopwords", Filter.by(word -> !isStopWord(word)))
+ .apply("(6) Count words", Count.perElement());
+ // We convert the PCollection to String so that we can write it to file
+ wordCount.apply(MapElements.into(TypeDescriptors.strings())
+ .via(count -> count.getKey() + " --> " + count.getValue()))
+ .apply(TextIO.write().to(outputFilePath));
+ // Finally we must run the pipeline, otherwise it's only a definition
+ p.run().waitUntilFinish();
+ return true;
+ }
+
+ public static boolean isStopWord(String word) {
+ String[] stopwords = {"am", "are", "is", "i", "you", "me",
+ "he", "she", "they", "them", "was",
+ "were", "from", "in", "of", "to", "be",
+ "him", "her", "us", "and", "or"};
+ for (String stopword : stopwords) {
+ if (stopword.compareTo(word) == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static String trim(String word) {
+ return word.replace("(","")
+ .replace(")", "")
+ .replace(",", "")
+ .replace(".", "")
+ .replace("\"", "")
+ .replace("'", "")
+ .replace(":", "")
+ .replace(";", "")
+ .replace("-", "")
+ .replace("?", "")
+ .replace("!", "");
+ }
+
+}
diff --git a/apache-beam/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java b/apache-beam/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java
new file mode 100644
index 0000000000..f2558635dc
--- /dev/null
+++ b/apache-beam/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.apache.beam.intro;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.baeldung.apache.beam.intro.WordCount;
+
+public class WordCountUnitTest {
+
+ @Test
+ // @Ignore
+ public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
+ boolean jobDone = WordCount.wordCount("src/test/resources/wordcount.txt", "target/output");
+ assertTrue(jobDone);
+ }
+
+}
diff --git a/apache-beam/src/test/resources/wordcount.txt b/apache-beam/src/test/resources/wordcount.txt
new file mode 100644
index 0000000000..542385379b
--- /dev/null
+++ b/apache-beam/src/test/resources/wordcount.txt
@@ -0,0 +1,16 @@
+We've all heard the scare stories about North Korea: the homemade nuclear arsenal built while their people starve and then aimed imprecisely at the rest of the world, a
+leader so deluded he makes L Ron Hubbard look like a man excessively overburdened with self-doubt and their deep-seated belief that foreign capitalists will invade at any
+moment and steal all their bauxite.
+The popular portrayal of this Marxist nation is something like one of the more harrowing episodes of M*A*S*H, only with the cast of wacky characters replaced by twitchy,
+heavily armed Stalinist meth addicts
+Cracked would like to take a moment to celebrate the good things about North Korea though, the things that the country's enemies prefer to suppress as part of their politically
+motivated jealousy. Like how no different to you and me, there's nothing every North Korean likes more after an 18 hour shift at the phosphorus plant than a nice beer to go with
+his dried fish ration. Ever attentive to its people's needs and in the twinkling of a decade, North Korea's leadership bought, disassembled, transported and rebuilt a British
+brewery in order to discover and reproduce the secrets of beer and then brew the sweet nectar for its hardworking people, up to 18 bottles at a time. And with minimal fatalities.
+When was the last time YOUR leader got a beer for YOU, American? (NB do not answer this question if you are Henry Louis Gates).
+Or how about the fried chicken restaurant that downtown Pyongyang boasts? Yes real chicken, fried and then delivered to your sleeping cube, with optional beer if you like! You
+don't even have to remove the feathers or pull out the gizzard yourself. Mostly. Americans must eat their fried chicken from a bucket, like swine, sold by a company so secretive
+that even the very blend of seasoning used is intentionally kept from them. And they call North Korea paranoid?
+And how many nations would entertain the syphilitic, bourgeois ramblings of Bill Clinton let alone permit him anywhere near their proud womenfolk? Only wise Kim Jong Il could see
+past Bill's many, many imperfections and treat him with the pity and kindness he deserves, accepting his feeble pleas to pardon the American spies rightly convicted of photographing
+the nation's sensitive beetroot fields.
diff --git a/core-java-modules/core-java-perf/src/main/java/com/baeldung/threaddump/ThreadDump.java b/core-java-modules/core-java-perf/src/main/java/com/baeldung/threaddump/ThreadDump.java
new file mode 100644
index 0000000000..17bc840b8d
--- /dev/null
+++ b/core-java-modules/core-java-perf/src/main/java/com/baeldung/threaddump/ThreadDump.java
@@ -0,0 +1,28 @@
+package com.baeldung.threaddump;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class ThreadDump {
+
+ public static void main(String[] args) throws IOException {
+ threadDump(true, true);
+ }
+
+ private static void threadDump(boolean lockedMonitors, boolean lockedSynchronizers) throws IOException {
+ Path threadDumpFile = Paths.get("ThreadDump.txt");
+
+ StringBuffer threadDump = new StringBuffer(System.lineSeparator());
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) {
+ threadDump.append(threadInfo.toString());
+ }
+ Files.write(threadDumpFile, threadDump.toString().getBytes());
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 0bcfac7963..2cefcc284f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -862,6 +862,7 @@
antlr
apache-avro
+ apache-beam
apache-bval
apache-curator
apache-cxf
diff --git a/spring-5/src/main/java/com/baeldung/version/VersionObtainer.java b/spring-5/src/main/java/com/baeldung/version/VersionObtainer.java
new file mode 100644
index 0000000000..392cc44a72
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/version/VersionObtainer.java
@@ -0,0 +1,20 @@
+package com.baeldung.version;
+
+import org.springframework.boot.system.JavaVersion;
+import org.springframework.boot.system.SystemProperties;
+import org.springframework.core.SpringVersion;
+
+public class VersionObtainer {
+
+ public String getSpringVersion() {
+ return SpringVersion.getVersion();
+ }
+
+ public String getJavaVersion() {
+ return JavaVersion.getJavaVersion().toString();
+ }
+
+ public String getJdkVersion() {
+ return SystemProperties.get("java.version");
+ }
+}
diff --git a/spring-5/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java b/spring-5/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java
new file mode 100644
index 0000000000..6d77cd1403
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/version/VersionObtainerUnitTest.java
@@ -0,0 +1,30 @@
+package com.baeldung.version;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(classes = VersionObtainer.class)
+public class VersionObtainerUnitTest {
+
+ public VersionObtainer version = new VersionObtainer();
+
+ @Test
+ public void testGetSpringVersion() {
+ String res = version.getSpringVersion();
+ assertThat(res).isNotEmpty();
+ }
+
+ @Test
+ public void testGetJdkVersion() {
+ String res = version.getJdkVersion();
+ assertThat(res).isNotEmpty();
+ }
+
+ @Test
+ public void testGetJavaVersion() {
+ String res = version.getJavaVersion();
+ assertThat(res).isNotEmpty();
+ }
+}
diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/Credentials.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/Credentials.java
new file mode 100644
index 0000000000..e51937cf57
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/Credentials.java
@@ -0,0 +1,28 @@
+package com.baeldung.boot.configurationproperties;
+
+public class Credentials {
+
+ private String username;
+ private String password;
+
+ public Credentials(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/CustomCredentialsConverter.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/CustomCredentialsConverter.java
new file mode 100644
index 0000000000..ef160c8c9a
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/CustomCredentialsConverter.java
@@ -0,0 +1,16 @@
+package com.baeldung.boot.configurationproperties;
+
+import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationPropertiesBinding
+public class CustomCredentialsConverter implements Converter {
+
+ @Override
+ public Credentials convert(String source) {
+ String[] data = source.split(",");
+ return new Credentials(data[0], data[1]);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java
new file mode 100644
index 0000000000..e23b30759b
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/MailServer.java
@@ -0,0 +1,59 @@
+package com.baeldung.boot.configurationproperties;
+
+import java.util.Map;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.validation.annotation.Validated;
+
+@Configuration
+@ConfigurationProperties(prefix = "validate")
+@PropertySource("classpath:property-validation.properties")
+@Validated
+public class MailServer {
+
+ @NotNull
+ @NotEmpty
+ private Map propertiesMap;
+
+ @Valid
+ private MailConfig mailConfig = new MailConfig();
+
+ public static class MailConfig {
+
+ @NotBlank
+ @Email
+ private String address;
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+ }
+
+ public Map getPropertiesMap() {
+ return propertiesMap;
+ }
+
+ public void setPropertiesMap(Map propertiesMap) {
+ this.propertiesMap = propertiesMap;
+ }
+
+ public MailConfig getMailConfig() {
+ return mailConfig;
+ }
+
+ public void setMailConfig(MailConfig mailConfig) {
+ this.mailConfig = mailConfig;
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/PropertyConversion.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/PropertyConversion.java
new file mode 100644
index 0000000000..9b2ea39299
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/PropertyConversion.java
@@ -0,0 +1,67 @@
+package com.baeldung.boot.configurationproperties;
+
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.convert.DataSizeUnit;
+import org.springframework.boot.convert.DurationUnit;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.unit.DataSize;
+import org.springframework.util.unit.DataUnit;
+
+@Configuration
+@ConfigurationProperties(prefix = "server")
+public class PropertyConversion {
+
+ private DataSize uploadSpeed;
+
+ @DataSizeUnit(DataUnit.GIGABYTES)
+ private DataSize downloadSpeed;
+
+ private Duration backupDay;
+
+ @DurationUnit(ChronoUnit.HOURS)
+ private Duration backupHour;
+
+ private Credentials credentials;
+
+ public Duration getBackupDay() {
+ return backupDay;
+ }
+
+ public void setBackupDay(Duration backupDay) {
+ this.backupDay = backupDay;
+ }
+
+ public Duration getBackupHour() {
+ return backupHour;
+ }
+
+ public void setBackupHour(Duration backupHour) {
+ this.backupHour = backupHour;
+ }
+
+ public DataSize getUploadSpeed() {
+ return uploadSpeed;
+ }
+
+ public void setUploadSpeed(DataSize uploadSpeed) {
+ this.uploadSpeed = uploadSpeed;
+ }
+
+ public DataSize getDownloadSpeed() {
+ return downloadSpeed;
+ }
+
+ public void setDownloadSpeed(DataSize downloadSpeed) {
+ this.downloadSpeed = downloadSpeed;
+ }
+
+ public Credentials getCredentials() {
+ return credentials;
+ }
+
+ public void setCredentials(Credentials credentials) {
+ this.credentials = credentials;
+ }
+}
diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/ServerConfig.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/ServerConfig.java
new file mode 100644
index 0000000000..0c9e62445a
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/ServerConfig.java
@@ -0,0 +1,43 @@
+package com.baeldung.boot.configurationproperties;
+
+import java.util.Map;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties(prefix = "server")
+public class ServerConfig {
+
+ private Address address;
+ private Map resourcesPath;
+
+ public static class Address {
+
+ private String ip;
+
+ public String getIp() {
+ return ip;
+ }
+
+ public void setIp(String ip) {
+ this.ip = ip;
+ }
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public Map getResourcesPath() {
+ return resourcesPath;
+ }
+
+ public void setResourcesPath(Map resourcesPath) {
+ this.resourcesPath = resourcesPath;
+ }
+}
diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/ServerConfigFactory.java b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/ServerConfigFactory.java
new file mode 100644
index 0000000000..ca85d59112
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/configurationproperties/ServerConfigFactory.java
@@ -0,0 +1,15 @@
+package com.baeldung.boot.configurationproperties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ServerConfigFactory {
+
+ @Bean(name = "default_bean")
+ @ConfigurationProperties(prefix = "server.default")
+ public ServerConfig getDefaultConfigs() {
+ return new ServerConfig();
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/main/resources/property-validation.properties b/spring-boot-modules/spring-boot-testing/src/main/resources/property-validation.properties
new file mode 100644
index 0000000000..6b4c881dc0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/main/resources/property-validation.properties
@@ -0,0 +1,4 @@
+validate.propertiesMap.first=prop1
+validate.propertiesMap.second=prop2
+
+validate.mail_config.address=user1@test
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingPropertiesToBeanMethodsUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingPropertiesToBeanMethodsUnitTest.java
new file mode 100644
index 0000000000..82c2a55c32
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingPropertiesToBeanMethodsUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.boot.configurationproperties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@EnableConfigurationProperties(value = ServerConfig.class)
+@ContextConfiguration(classes = ServerConfigFactory.class)
+@TestPropertySource("classpath:server-config-test.properties")
+public class BindingPropertiesToBeanMethodsUnitTest {
+
+ @Autowired
+ @Qualifier("default_bean")
+ private ServerConfig serverConfig;
+
+ @Test
+ void givenBeanAnnotatedMethod_whenBindingProperties_thenAllFieldsAreSet() {
+ assertEquals("192.168.0.2", serverConfig.getAddress()
+ .getIp());
+
+ Map expectedResourcesPath = new HashMap<>();
+ expectedResourcesPath.put("imgs", "/root/def/imgs");
+ assertEquals(expectedResourcesPath, serverConfig.getResourcesPath());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingPropertiesToUserDefinedPOJOUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingPropertiesToUserDefinedPOJOUnitTest.java
new file mode 100644
index 0000000000..9db906fa04
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingPropertiesToUserDefinedPOJOUnitTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.boot.configurationproperties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@EnableConfigurationProperties(value = ServerConfig.class)
+@TestPropertySource("classpath:server-config-test.properties")
+public class BindingPropertiesToUserDefinedPOJOUnitTest {
+
+ @Autowired
+ private ServerConfig serverConfig;
+
+ @Test
+ void givenUserDefinedPOJO_whenBindingPropertiesFile_thenAllFieldsAreSet() {
+ assertEquals("192.168.0.1", serverConfig.getAddress()
+ .getIp());
+
+ Map expectedResourcesPath = new HashMap<>();
+ expectedResourcesPath.put("imgs", "/root/imgs");
+ assertEquals(expectedResourcesPath, serverConfig.getResourcesPath());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingYMLPropertiesUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingYMLPropertiesUnitTest.java
new file mode 100644
index 0000000000..5543f5e9e8
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingYMLPropertiesUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.boot.configurationproperties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
+@EnableConfigurationProperties(value = ServerConfig.class)
+@ActiveProfiles("test")
+public class BindingYMLPropertiesUnitTest {
+
+ @Autowired
+ private ServerConfig serverConfig;
+
+ @Test
+ void whenBindingYMLConfigFile_thenAllFieldsAreSet() {
+ assertEquals("192.168.0.4", serverConfig.getAddress()
+ .getIp());
+
+ Map expectedResourcesPath = new HashMap<>();
+ expectedResourcesPath.put("imgs", "/etc/test/imgs");
+ assertEquals(expectedResourcesPath, serverConfig.getResourcesPath());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/OverridingConfigurationPropertiesUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/OverridingConfigurationPropertiesUnitTest.java
new file mode 100644
index 0000000000..2779b0a313
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/OverridingConfigurationPropertiesUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.boot.configurationproperties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@EnableConfigurationProperties(value = MailServer.class)
+@TestPropertySource(properties = { "validate.mail_config.address=new_user@test" })
+public class OverridingConfigurationPropertiesUnitTest {
+
+ @Autowired
+ private MailServer mailServer;
+
+ @Test
+ void givenUsingPropertiesAttribute_whenAssiginingNewValueToProprty_thenSpringUsesNewValue() {
+ assertEquals("new_user@test", mailServer.getMailConfig()
+ .getAddress());
+
+ Map expectedMap = new HashMap<>();
+ expectedMap.put("first", "prop1");
+ expectedMap.put("second", "prop2");
+ assertEquals(expectedMap, mailServer.getPropertiesMap());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java
new file mode 100644
index 0000000000..939471dd67
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/PropertyValidationUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.boot.configurationproperties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import javax.validation.Validation;
+import javax.validation.Validator;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@EnableConfigurationProperties(value = MailServer.class)
+@TestPropertySource("classpath:property-validation-test.properties")
+public class PropertyValidationUnitTest {
+
+ @Autowired
+ private MailServer mailServer;
+
+ private static Validator propertyValidator;
+
+ @BeforeAll
+ public static void setup() {
+ propertyValidator = Validation.buildDefaultValidatorFactory()
+ .getValidator();
+ }
+
+ @Test
+ void whenBindingPropertiesToValidatedBeans_thenConstrainsAreChecked() {
+ assertEquals(0, propertyValidator.validate(mailServer.getPropertiesMap())
+ .size());
+ assertEquals(0, propertyValidator.validate(mailServer.getMailConfig())
+ .size());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/SpringPropertiesConversionUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/SpringPropertiesConversionUnitTest.java
new file mode 100644
index 0000000000..3f2da2a669
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/SpringPropertiesConversionUnitTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.boot.configurationproperties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.time.Duration;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.util.unit.DataSize;
+
+@ExtendWith(SpringExtension.class)
+@EnableConfigurationProperties(value = PropertyConversion.class)
+@ContextConfiguration(classes = CustomCredentialsConverter.class)
+@TestPropertySource("classpath:spring-conversion-test.properties")
+public class SpringPropertiesConversionUnitTest {
+
+ @Autowired
+ private PropertyConversion propertyConversion;
+
+ @Test
+ void whenUsingSpringDefaultSizeConversion_thenDataSizeObjectIsSet() {
+ assertEquals(DataSize.ofMegabytes(500), propertyConversion.getUploadSpeed());
+ assertEquals(DataSize.ofGigabytes(10), propertyConversion.getDownloadSpeed());
+ }
+
+ @Test
+ void whenUsingSpringDefaultDurationConversion_thenDurationObjectIsSet() {
+ assertEquals(Duration.ofDays(1), propertyConversion.getBackupDay());
+ assertEquals(Duration.ofHours(8), propertyConversion.getBackupHour());
+ }
+
+ @Test
+ void whenRegisteringCustomCredentialsConverter_thenCredentialsAreParsed() {
+ assertEquals("user", propertyConversion.getCredentials()
+ .getUsername());
+ assertEquals("123", propertyConversion.getCredentials()
+ .getPassword());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/application.yml b/spring-boot-modules/spring-boot-testing/src/test/resources/application.yml
new file mode 100644
index 0000000000..1b46b0f1ff
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/resources/application.yml
@@ -0,0 +1,15 @@
+spring:
+ profiles: test
+server:
+ address:
+ ip: 192.168.0.4
+ resources_path:
+ imgs: /etc/test/imgs
+---
+spring:
+ profiles: dev
+server:
+ address:
+ ip: 192.168.0.5
+ resources_path:
+ imgs: /etc/dev/imgs
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/property-validation-test.properties b/spring-boot-modules/spring-boot-testing/src/test/resources/property-validation-test.properties
new file mode 100644
index 0000000000..6b4c881dc0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/resources/property-validation-test.properties
@@ -0,0 +1,4 @@
+validate.propertiesMap.first=prop1
+validate.propertiesMap.second=prop2
+
+validate.mail_config.address=user1@test
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/server-config-test.properties b/spring-boot-modules/spring-boot-testing/src/test/resources/server-config-test.properties
new file mode 100644
index 0000000000..62b23ed1d6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/resources/server-config-test.properties
@@ -0,0 +1,6 @@
+server.address.ip=192.168.0.1
+server.resources_path.imgs=/root/imgs
+
+# default config
+server.default.address.ip=192.168.0.2
+server.default.resources_path.imgs=/root/def/imgs
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/spring-conversion-test.properties b/spring-boot-modules/spring-boot-testing/src/test/resources/spring-conversion-test.properties
new file mode 100644
index 0000000000..87444cee10
--- /dev/null
+++ b/spring-boot-modules/spring-boot-testing/src/test/resources/spring-conversion-test.properties
@@ -0,0 +1,10 @@
+# bandwidth
+server.upload_speed=500MB
+server.download_speed=10
+
+# backup date
+server.backup_day=1d
+server.backup_hour=8
+
+# custom converter
+server.credentials=user,123
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java
index 2bd0da48d2..e051e5a853 100644
--- a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java
+++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/Application.java
@@ -3,9 +3,11 @@ package org.baeldung.custom;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication
+@ComponentScan("org.baeldung.custom")
@PropertySource("classpath:application-defaults.properties")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java
index 739e4d3417..06357650dc 100644
--- a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java
+++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/custom/config/SecurityConfig.java
@@ -2,11 +2,27 @@ package org.baeldung.custom.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+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.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
-public class SecurityConfig {
+@EnableWebSecurity
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(final HttpSecurity http) throws Exception {
+ http.csrf()
+ .disable()
+ .authorizeRequests()
+ .anyRequest()
+ .authenticated()
+ .and()
+ .formLogin()
+ .permitAll();
+ }
@Bean
public PasswordEncoder encoder() {
diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java
index b68abbaed1..d77414c54e 100644
--- a/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java
+++ b/spring-security-modules/spring-security-mvc-boot-1/src/main/java/org/baeldung/ip/IpApplication.java
@@ -3,9 +3,11 @@ package org.baeldung.ip;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication
+@ComponentScan("org.baeldung.ip")
@PropertySource("classpath:application-defaults.properties")
public class IpApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java
index dfcfcad609..e199411e58 100644
--- a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java
+++ b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/ApplicationLiveTest.java
@@ -13,7 +13,7 @@ import io.restassured.specification.RequestSpecification;
import org.junit.Test;
import org.springframework.http.MediaType;
-
+// In order to execute these tests, org.baeldung.custom.Application needs to be running.
public class ApplicationLiveTest {
@Test
diff --git a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java
index e12e2f87b0..761f5450f7 100644
--- a/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java
+++ b/spring-security-modules/spring-security-mvc-boot-1/src/test/java/org/baeldung/web/IpLiveTest.java
@@ -8,6 +8,7 @@ import io.restassured.response.Response;
import org.junit.Test;
+// In order to execute these tests, org.baeldung.ip.IpApplication needs to be running.
public class IpLiveTest {
@Test
diff --git a/testing-modules/mockito/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java b/testing-modules/mockito/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java
index dd41d98b57..9dd98f184b 100644
--- a/testing-modules/mockito/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java
+++ b/testing-modules/mockito/src/test/java/com/baeldung/mockito/voidmethods/MockitoVoidMethodsUnitTest.java
@@ -16,48 +16,51 @@ public class MockitoVoidMethodsUnitTest {
@Test
public void whenAddCalledVerified() {
- MyList mockVoid = mock(MyList.class);
- mockVoid.add(0, "");
- verify(mockVoid, times(1)).add(0, "");
+ MyList myList = mock(MyList.class);
+ myList.add(0, "");
+
+ verify(myList, times(1)).add(0, "");
}
@Test(expected = Exception.class)
public void givenNull_addThrows() {
- MyList mockVoid = mock(MyList.class);
- doThrow().when(mockVoid).add(isA(Integer.class), isNull());
- mockVoid.add(0, null);
+ MyList myList = mock(MyList.class);
+ doThrow().when(myList).add(isA(Integer.class), isNull());
+
+ myList.add(0, null);
}
@Test
public void whenAddCalledValueCaptured() {
- MyList mockVoid = mock(MyList.class);
+ MyList myList = mock(MyList.class);
ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class);
- doNothing().when(mockVoid).add(any(Integer.class), valueCapture.capture());
- mockVoid.add(0, "captured");
+ doNothing().when(myList).add(any(Integer.class), valueCapture.capture());
+ myList.add(0, "captured");
+
assertEquals("captured", valueCapture.getValue());
}
@Test
public void whenAddCalledAnswered() {
- MyList mockVoid = mock(MyList.class);
- doAnswer((Answer) invocation -> {
+ MyList myList = mock(MyList.class);
+ doAnswer(invocation -> {
Object arg0 = invocation.getArgument(0);
Object arg1 = invocation.getArgument(1);
//do something with the arguments here
assertEquals(3, arg0);
assertEquals("answer me", arg1);
-
return null;
- }).when(mockVoid).add(any(Integer.class), any(String.class));
- mockVoid.add(3, "answer me");
+ }).when(myList).add(any(Integer.class), any(String.class));
+ myList.add(3, "answer me");
}
@Test
public void whenAddCalledRealMethodCalled() {
- MyList mockVoid = mock(MyList.class);
- doCallRealMethod().when(mockVoid).add(any(Integer.class), any(String.class));
- mockVoid.add(1, "real");
- verify(mockVoid, times(1)).add(1, "real");
+ MyList myList = mock(MyList.class);
+ doCallRealMethod().when(myList).add(any(Integer.class), any(String.class));
+ myList.add(1, "real");
+
+ verify(myList, times(1)).add(1, "real");
}
}