Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
		
						commit
						946fb3b33a
					
				| @ -39,6 +39,16 @@ | |||||||
|             <artifactId>guava</artifactId> |             <artifactId>guava</artifactId> | ||||||
|             <version>${guava.version}</version> |             <version>${guava.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.fasterxml.jackson.core</groupId> | ||||||
|  |             <artifactId>jackson-databind</artifactId> | ||||||
|  |             <version>${jackson.version}</version> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.junit.platform</groupId> | ||||||
|  |             <artifactId>junit-platform-commons</artifactId> | ||||||
|  |             <version>${junit.platform.version}</version> | ||||||
|  |         </dependency> | ||||||
| 
 | 
 | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.assertj</groupId> |             <groupId>org.assertj</groupId> | ||||||
| @ -66,6 +76,8 @@ | |||||||
|         <commons-codec.version>1.11</commons-codec.version> |         <commons-codec.version>1.11</commons-codec.version> | ||||||
|         <commons-math3.version>3.6.1</commons-math3.version> |         <commons-math3.version>3.6.1</commons-math3.version> | ||||||
|         <guava.version>28.1-jre</guava.version> |         <guava.version>28.1-jre</guava.version> | ||||||
|  |         <jackson.version>2.10.2</jackson.version> | ||||||
|  |         <junit.platform.version>1.6.0</junit.platform.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
| </project> | </project> | ||||||
| @ -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<Edge> getMST() { | ||||||
|  |         return mst; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getTotalWeight() { | ||||||
|  |         return totalWeight; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String toString() { | ||||||
|  |         return "MST: " + mst.toString() + " | Total Weight: " + totalWeight; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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<Edge> iterableTree(int i) { | ||||||
|  |         return trees[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Iterable<Edge> getAllEdges() { | ||||||
|  |         Iterable<Edge> 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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,65 @@ | |||||||
|  | package com.baeldung.algorithms.boruvka; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | public class Input { | ||||||
|  |     private int nodes; | ||||||
|  |     private int edges; | ||||||
|  |     private List<E> 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<E> getEdgeList() { | ||||||
|  |         return edgeList; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setEdgeList(List<E> 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; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,63 @@ | |||||||
|  | package com.baeldung.algorithms.boruvka; | ||||||
|  | 
 | ||||||
|  | import java.util.Iterator; | ||||||
|  | 
 | ||||||
|  | public class Tree implements Iterable<Edge> { | ||||||
|  |     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<Edge> iterator() { | ||||||
|  |         return new LinkedIterator(root); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private class LinkedIterator implements Iterator<Edge> { | ||||||
|  |         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; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								algorithms-miscellaneous-5/src/test/resources/input.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								algorithms-miscellaneous-5/src/test/resources/input.json
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
|  | 		} | ||||||
|  | 	] | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								apache-beam/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								apache-beam/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||||
|  |     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"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>parent-modules</artifactId> | ||||||
|  |         <version>1.0.0-SNAPSHOT</version> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <groupId>com.baeldung.apache</groupId> | ||||||
|  |     <artifactId>apache-beam</artifactId> | ||||||
|  |     <version>0.0.1-SNAPSHOT</version> | ||||||
|  | 
 | ||||||
|  |     <dependencies> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.apache.beam</groupId> | ||||||
|  |             <artifactId>beam-sdks-java-core</artifactId> | ||||||
|  |             <version>${beam.version}</version> | ||||||
|  |         </dependency> | ||||||
|  |         <!-- runtime scoped --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.apache.beam</groupId> | ||||||
|  |             <artifactId>beam-runners-direct-java</artifactId> | ||||||
|  |             <version>${beam.version}</version> | ||||||
|  |             <scope>runtime</scope> | ||||||
|  |         </dependency> | ||||||
|  |         <!-- test scoped --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.assertj</groupId> | ||||||
|  |             <artifactId>assertj-core</artifactId> | ||||||
|  |             <version>${assertj.version}</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  | 
 | ||||||
|  |     <properties> | ||||||
|  |         <beam.version>2.19.0</beam.version> | ||||||
|  |         <assertj.version>3.6.1</assertj.version> | ||||||
|  |     </properties> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -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<KV<String, Long>> 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("!", ""); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								apache-beam/src/test/resources/wordcount.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								apache-beam/src/test/resources/wordcount.txt
									
									
									
									
									
										Normal file
									
								
							| @ -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. | ||||||
| @ -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()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								pom.xml
									
									
									
									
									
								
							| @ -862,6 +862,7 @@ | |||||||
|                 <module>antlr</module> |                 <module>antlr</module> | ||||||
| 
 | 
 | ||||||
|                 <module>apache-avro</module> |                 <module>apache-avro</module> | ||||||
|  |                 <module>apache-beam</module> | ||||||
|                 <module>apache-bval</module> |                 <module>apache-bval</module> | ||||||
|                 <module>apache-curator</module> |                 <module>apache-curator</module> | ||||||
|                 <module>apache-cxf</module> |                 <module>apache-cxf</module> | ||||||
|  | |||||||
| @ -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"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String, Credentials> { | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Credentials convert(String source) { | ||||||
|  |         String[] data = source.split(","); | ||||||
|  |         return new Credentials(data[0], data[1]); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String, @NotBlank String> 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<String, String> getPropertiesMap() { | ||||||
|  |         return propertiesMap; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setPropertiesMap(Map<String, String> propertiesMap) { | ||||||
|  |         this.propertiesMap = propertiesMap; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public MailConfig getMailConfig() { | ||||||
|  |         return mailConfig; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setMailConfig(MailConfig mailConfig) { | ||||||
|  |         this.mailConfig = mailConfig; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String, String> 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<String, String> getResourcesPath() { | ||||||
|  |         return resourcesPath; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setResourcesPath(Map<String, String> resourcesPath) { | ||||||
|  |         this.resourcesPath = resourcesPath; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | validate.propertiesMap.first=prop1 | ||||||
|  | validate.propertiesMap.second=prop2 | ||||||
|  | 
 | ||||||
|  | validate.mail_config.address=user1@test | ||||||
| @ -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<String, String> expectedResourcesPath = new HashMap<>(); | ||||||
|  |         expectedResourcesPath.put("imgs", "/root/def/imgs"); | ||||||
|  |         assertEquals(expectedResourcesPath, serverConfig.getResourcesPath()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String, String> expectedResourcesPath = new HashMap<>(); | ||||||
|  |         expectedResourcesPath.put("imgs", "/root/imgs"); | ||||||
|  |         assertEquals(expectedResourcesPath, serverConfig.getResourcesPath()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String, String> expectedResourcesPath = new HashMap<>(); | ||||||
|  |         expectedResourcesPath.put("imgs", "/etc/test/imgs"); | ||||||
|  |         assertEquals(expectedResourcesPath, serverConfig.getResourcesPath()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<String, String> expectedMap = new HashMap<>(); | ||||||
|  |         expectedMap.put("first", "prop1"); | ||||||
|  |         expectedMap.put("second", "prop2"); | ||||||
|  |         assertEquals(expectedMap, mailServer.getPropertiesMap()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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 | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | validate.propertiesMap.first=prop1 | ||||||
|  | validate.propertiesMap.second=prop2 | ||||||
|  | 
 | ||||||
|  | validate.mail_config.address=user1@test | ||||||
| @ -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 | ||||||
| @ -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 | ||||||
| @ -3,9 +3,11 @@ package org.baeldung.custom; | |||||||
| import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
| import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; | ||||||
|  | import org.springframework.context.annotation.ComponentScan; | ||||||
| import org.springframework.context.annotation.PropertySource; | import org.springframework.context.annotation.PropertySource; | ||||||
| 
 | 
 | ||||||
| @SpringBootApplication | @SpringBootApplication | ||||||
|  | @ComponentScan("org.baeldung.custom") | ||||||
| @PropertySource("classpath:application-defaults.properties") | @PropertySource("classpath:application-defaults.properties") | ||||||
| public class Application extends SpringBootServletInitializer { | public class Application extends SpringBootServletInitializer { | ||||||
|     public static void main(String[] args) { |     public static void main(String[] args) { | ||||||
|  | |||||||
| @ -2,11 +2,27 @@ package org.baeldung.custom.config; | |||||||
| 
 | 
 | ||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| import org.springframework.context.annotation.Configuration; | 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.bcrypt.BCryptPasswordEncoder; | ||||||
| import org.springframework.security.crypto.password.PasswordEncoder; | import org.springframework.security.crypto.password.PasswordEncoder; | ||||||
| 
 | 
 | ||||||
| @Configuration | @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 |     @Bean | ||||||
|     public PasswordEncoder encoder() { |     public PasswordEncoder encoder() { | ||||||
|  | |||||||
| @ -3,9 +3,11 @@ package org.baeldung.ip; | |||||||
| import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
| import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; | ||||||
|  | import org.springframework.context.annotation.ComponentScan; | ||||||
| import org.springframework.context.annotation.PropertySource; | import org.springframework.context.annotation.PropertySource; | ||||||
| 
 | 
 | ||||||
| @SpringBootApplication | @SpringBootApplication | ||||||
|  | @ComponentScan("org.baeldung.ip") | ||||||
| @PropertySource("classpath:application-defaults.properties") | @PropertySource("classpath:application-defaults.properties") | ||||||
| public class IpApplication extends SpringBootServletInitializer { | public class IpApplication extends SpringBootServletInitializer { | ||||||
|     public static void main(String[] args) { |     public static void main(String[] args) { | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ import io.restassured.specification.RequestSpecification; | |||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| import org.springframework.http.MediaType; | import org.springframework.http.MediaType; | ||||||
| 
 | 
 | ||||||
| 
 | // In order to execute these tests, org.baeldung.custom.Application needs to be running. | ||||||
| public class ApplicationLiveTest { | public class ApplicationLiveTest { | ||||||
|      |      | ||||||
|     @Test |     @Test | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import io.restassured.response.Response; | |||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | // In order to execute these tests, org.baeldung.ip.IpApplication needs to be running. | ||||||
| public class IpLiveTest { | public class IpLiveTest { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | |||||||
| @ -16,48 +16,51 @@ public class MockitoVoidMethodsUnitTest { | |||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void whenAddCalledVerified() { |     public void whenAddCalledVerified() { | ||||||
|         MyList mockVoid = mock(MyList.class); |         MyList myList = mock(MyList.class); | ||||||
|         mockVoid.add(0, ""); |         myList.add(0, ""); | ||||||
|         verify(mockVoid, times(1)).add(0, ""); | 
 | ||||||
|  |         verify(myList, times(1)).add(0, ""); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test(expected = Exception.class) |     @Test(expected = Exception.class) | ||||||
|     public void givenNull_addThrows() { |     public void givenNull_addThrows() { | ||||||
|         MyList mockVoid = mock(MyList.class); |         MyList myList = mock(MyList.class); | ||||||
|         doThrow().when(mockVoid).add(isA(Integer.class), isNull()); |         doThrow().when(myList).add(isA(Integer.class), isNull()); | ||||||
|         mockVoid.add(0, null); | 
 | ||||||
|  |         myList.add(0, null); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void whenAddCalledValueCaptured() { |     public void whenAddCalledValueCaptured() { | ||||||
|         MyList mockVoid = mock(MyList.class); |         MyList myList = mock(MyList.class); | ||||||
|         ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class); |         ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class); | ||||||
|         doNothing().when(mockVoid).add(any(Integer.class), valueCapture.capture()); |         doNothing().when(myList).add(any(Integer.class), valueCapture.capture()); | ||||||
|         mockVoid.add(0, "captured"); |         myList.add(0, "captured"); | ||||||
|  | 
 | ||||||
|         assertEquals("captured", valueCapture.getValue()); |         assertEquals("captured", valueCapture.getValue()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void whenAddCalledAnswered() { |     public void whenAddCalledAnswered() { | ||||||
|         MyList mockVoid = mock(MyList.class); |         MyList myList = mock(MyList.class); | ||||||
|         doAnswer((Answer<Void>) invocation -> { |         doAnswer(invocation -> { | ||||||
|             Object arg0 = invocation.getArgument(0); |             Object arg0 = invocation.getArgument(0); | ||||||
|             Object arg1 = invocation.getArgument(1); |             Object arg1 = invocation.getArgument(1); | ||||||
| 
 | 
 | ||||||
|             //do something with the arguments here |             //do something with the arguments here | ||||||
|             assertEquals(3, arg0); |             assertEquals(3, arg0); | ||||||
|             assertEquals("answer me", arg1); |             assertEquals("answer me", arg1); | ||||||
| 
 |  | ||||||
|             return null; |             return null; | ||||||
|         }).when(mockVoid).add(any(Integer.class), any(String.class)); |         }).when(myList).add(any(Integer.class), any(String.class)); | ||||||
|         mockVoid.add(3, "answer me"); |         myList.add(3, "answer me"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void whenAddCalledRealMethodCalled() { |     public void whenAddCalledRealMethodCalled() { | ||||||
|         MyList mockVoid = mock(MyList.class); |         MyList myList = mock(MyList.class); | ||||||
|         doCallRealMethod().when(mockVoid).add(any(Integer.class), any(String.class)); |         doCallRealMethod().when(myList).add(any(Integer.class), any(String.class)); | ||||||
|         mockVoid.add(1, "real"); |         myList.add(1, "real"); | ||||||
|         verify(mockVoid, times(1)).add(1, "real"); |          | ||||||
|  |         verify(myList, times(1)).add(1, "real"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user