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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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…
Reference in New Issue