diff --git a/README.md b/README.md index 6dff78aa7a..1d916c8409 100644 --- a/README.md +++ b/README.md @@ -40,5 +40,3 @@ This tutorials project is being built **[>> HERE](https://rest-security.ci.cloud - [Apache Maven Standard Directory Layout](http://www.baeldung.com/maven-directory-structure) - [Apache Maven Tutorial](http://www.baeldung.com/maven) - [Designing a User Friendly Java Library](http://www.baeldung.com/design-a-user-friendly-java-library) -- [Java Service Provider Interface](http://www.baeldung.com/java-spi) -- [Java Streams vs Vavr Streams](http://www.baeldung.com/vavr-java-streams) diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java index 8b47fa0fdf..5ca2d626f1 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java @@ -148,7 +148,7 @@ public class Board { System.out.println("Game Draw"); break; case IN_PROGRESS: - System.out.println("Game In rogress"); + System.out.println("Game In Progress"); break; } } diff --git a/algorithms/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java b/algorithms/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java new file mode 100644 index 0000000000..1e9188f726 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java @@ -0,0 +1,139 @@ +package com.baeldung.algorithms.analysis; + +import org.junit.Test; + +public class AnalysisRunnerLiveTest { + + int n = 10; + int total = 0; + + @Test + public void whenConstantComplexity_thenConstantRuntime() { + + System.out.println("**** n = " + n + " ****"); + System.out.println(); + + // Constant Time + System.out.println("**** Constant time ****"); + + System.out.println("Hey - your input is: " + n); + System.out.println("Running time not dependent on input size!"); + System.out.println(); + } + + @Test + public void whenLogarithmicComplexity_thenLogarithmicRuntime() { + // Logarithmic Time + System.out.println("**** Logarithmic Time ****"); + for (int i = 1; i < n; i = i * 2) { + // System.out.println("Hey - I'm busy looking at: " + i); + total++; + } + System.out.println("Total amount of times run: " + total); + System.out.println(); + } + + @Test + public void whenLinearComplexity_thenLinearRuntime() { + // Linear Time + System.out.println("**** Linear Time ****"); + for (int i = 0; i < n; i++) { + // System.out.println("Hey - I'm busy looking at: " + i); + total++; + } + System.out.println("Total amount of times run: " + total); + System.out.println(); + + } + + @Test + public void whenNLogNComplexity_thenNLogNRuntime() { + // N Log N Time + System.out.println("**** nlogn Time ****"); + total = 0; + for ( + + int i = 1; i <= n; i++) { + for (int j = 1; j < n; j = j * 2) { + // System.out.println("Hey - I'm busy looking at: " + i + " and " + j); + total++; + } + } + System.out.println("Total amount of times run: " + total); + System.out.println(); + } + + @Test + public void whenQuadraticComplexity_thenQuadraticRuntime() { + // Quadratic Time + System.out.println("**** Quadratic Time ****"); + total = 0; + for ( + + int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + // System.out.println("Hey - I'm busy looking at: " + i + " and " + j); + total++; + } + } + System.out.println("Total amount of times run: " + total); + System.out.println(); + } + + @Test + public void whenCubicComplexity_thenCubicRuntime() { + // Cubic Time + System.out.println("**** Cubic Time ****"); + total = 0; + for ( + + int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + for (int k = 1; k <= n; k++) { + // System.out.println("Hey - I'm busy looking at: " + i + " and " + j + " and " + k); + total++; + } + } + } + System.out.println("Total amount of times run: " + total); + System.out.println(); + } + + @Test + public void whenExponentialComplexity_thenExponentialRuntime() { + // Exponential Time + System.out.println("**** Exponential Time ****"); + total = 0; + for ( + + int i = 1; i <= Math.pow(2, n); i++) { + // System.out.println("Hey - I'm busy looking at: " + i); + total++; + } + System.out.println("Total amount of times run: " + total); + System.out.println(); + } + + @Test + public void whenFactorialComplexity_thenFactorialRuntime() { + // Factorial Time + System.out.println("**** Factorial Time ****"); + total = 0; + for ( + + int i = 1; i <= + + factorial(n); i++) { + // System.out.println("Hey - I'm busy looking at: " + i); + total++; + } + System.out.println("Total amount of times run: " + total); + } + + static int factorial(int n) { + if (n == 0 || n == 1) + return 1; + else + return n * factorial(n - 1); + } +} diff --git a/animal-sniffer-mvn-plugin/pom.xml b/animal-sniffer-mvn-plugin/pom.xml index ab7b38f6e0..9ccc7354af 100644 --- a/animal-sniffer-mvn-plugin/pom.xml +++ b/animal-sniffer-mvn-plugin/pom.xml @@ -5,7 +5,7 @@ animal-sniffer-mvn-plugin jar 1.0-SNAPSHOT - example-animal-sniffer-mvn-plugin + animal-sniffer-mvn-plugin http://maven.apache.org diff --git a/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java b/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java index 5319208e85..7253238e80 100644 --- a/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java +++ b/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java @@ -1,25 +1,30 @@ package com.baeldung.poi.powerpoint; +import java.io.File; +import java.util.List; + import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XSLFShape; import org.apache.poi.xslf.usermodel.XSLFSlide; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; - -import java.io.File; -import java.util.List; +import org.junit.rules.TemporaryFolder; public class PowerPointIntegrationTest { private PowerPointHelper pph; private String fileLocation; private static final String FILE_NAME = "presentation.pptx"; + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { - File currDir = new File("."); + File currDir = tempFolder.newFolder(); String path = currDir.getAbsolutePath(); fileLocation = path.substring(0, path.length() - 1) + FILE_NAME; diff --git a/camel-api/pom.xml b/camel-api/pom.xml index 86f6713cd6..4e50828b96 100644 --- a/camel-api/pom.xml +++ b/camel-api/pom.xml @@ -5,7 +5,6 @@ com.example spring-boot-camel 0.0.1-SNAPSHOT - Spring-Boot - Camel API com.baeldung diff --git a/core-java-8/README.md b/core-java-8/README.md index df6d50ad30..2eb8d49983 100644 --- a/core-java-8/README.md +++ b/core-java-8/README.md @@ -52,4 +52,4 @@ - [Measure Elapsed Time in Java](http://www.baeldung.com/java-measure-elapsed-time) - [Java Optional – orElse() vs orElseGet()](http://www.baeldung.com/java-optional-or-else-vs-or-else-get) - [An Introduction to Java.util.Hashtable Class](http://www.baeldung.com/java-hash-table) - +- [Method Parameter Reflection in Java](http://www.baeldung.com/java-parameter-reflection) diff --git a/core-java-8/src/test/java/com/baeldung/java8/UnsignedArithmeticUnitTest.java b/core-java-8/src/test/java/com/baeldung/java8/UnsignedArithmeticUnitTest.java new file mode 100644 index 0000000000..e79c90b684 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/java8/UnsignedArithmeticUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.java8; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; +import static org.junit.Assert.assertEquals; + +public class UnsignedArithmeticUnitTest { + @Test + public void whenDoublingALargeByteNumber_thenOverflow() { + byte b1 = 100; + byte b2 = (byte) (b1 << 1); + + assertEquals(-56, b2); + } + + @Test + public void whenComparingNumbers_thenNegativeIsInterpretedAsUnsigned() { + int positive = Integer.MAX_VALUE; + int negative = Integer.MIN_VALUE; + + int signedComparison = Integer.compare(positive, negative); + assertEquals(1, signedComparison); + + int unsignedComparison = Integer.compareUnsigned(positive, negative); + assertEquals(-1, unsignedComparison); + + assertEquals(negative, positive + 1); + } + + @Test + public void whenDividingNumbers_thenNegativeIsInterpretedAsUnsigned() { + int positive = Integer.MAX_VALUE; + int negative = Integer.MIN_VALUE; + + assertEquals(-1, negative / positive); + assertEquals(1, Integer.divideUnsigned(negative, positive)); + + assertEquals(-1, negative % positive); + assertEquals(1, Integer.divideUnsigned(negative, positive)); + } + + @Test + public void whenParsingNumbers_thenNegativeIsInterpretedAsUnsigned() { + Throwable thrown = catchThrowable(() -> Integer.parseInt("2147483648")); + assertThat(thrown).isInstanceOf(NumberFormatException.class); + + assertEquals(Integer.MAX_VALUE + 1, Integer.parseUnsignedInt("2147483648")); + } + + @Test + public void whenFormattingNumbers_thenNegativeIsInterpretedAsUnsigned() { + String signedString = Integer.toString(Integer.MIN_VALUE); + assertEquals("-2147483648", signedString); + + String unsignedString = Integer.toUnsignedString(Integer.MIN_VALUE); + assertEquals("2147483648", unsignedString); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/typeinference/TypeInferenceUnitTest.java b/core-java-8/src/test/java/com/baeldung/typeinference/TypeInferenceUnitTest.java new file mode 100644 index 0000000000..b9600a18cb --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/typeinference/TypeInferenceUnitTest.java @@ -0,0 +1,87 @@ +package com.baeldung.typeinference; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +public class TypeInferenceUnitTest { + + @Test + public void givenNoTypeInference_whenInvokingGenericMethodsWithTypeParameters_ObjectsAreCreated() { + // Without type inference. code is verbose. + Map> mapOfMaps = new HashMap>(); + List strList = Collections. emptyList(); + List intList = Collections. emptyList(); + + assertTrue(mapOfMaps.isEmpty()); + assertTrue(strList.isEmpty()); + assertTrue(intList.isEmpty()); + } + + @Test + public void givenTypeInference_whenInvokingGenericMethodsWithoutTypeParameters_ObjectsAreCreated() { + // With type inference. code is concise. + List strListInferred = Collections.emptyList(); + List intListInferred = Collections.emptyList(); + + assertTrue(strListInferred.isEmpty()); + assertTrue(intListInferred.isEmpty()); + } + + @Test + public void givenJava7_whenInvokingCostructorWithoutTypeParameters_ObjectsAreCreated() { + // Type Inference for constructor using diamond operator. + Map> mapOfMapsInferred = new HashMap<>(); + + assertTrue(mapOfMapsInferred.isEmpty()); + assertEquals("public class java.util.HashMap", mapOfMapsInferred.getClass() + .toGenericString()); + } + + static List add(List list, T a, T b) { + list.add(a); + list.add(b); + return list; + } + + @Test + public void givenGenericMethod_WhenInvokedWithoutExplicitTypes_TypesAreInferred() { + // Generalized target-type inference + List strListGeneralized = add(new ArrayList<>(), "abc", "def"); + List intListGeneralized = add(new ArrayList<>(), 1, 2); + List numListGeneralized = add(new ArrayList<>(), 1, 2.0); + + assertEquals("public class java.util.ArrayList", strListGeneralized.getClass() + .toGenericString()); + assertFalse(intListGeneralized.isEmpty()); + assertEquals(2, numListGeneralized.size()); + } + + @Test + public void givenLambdaExpressions_whenParameterTypesNotSpecified_ParameterTypesAreInferred() { + // Type Inference and Lambda Expressions. + List intList = Arrays.asList(5, 3, 4, 2, 1); + Collections.sort(intList, (a, b) -> { + assertEquals("java.lang.Integer", a.getClass().getName()); + return a.compareTo(b); + }); + assertEquals("[1, 2, 3, 4, 5]", Arrays.toString(intList.toArray())); + + List strList = Arrays.asList("Red", "Blue", "Green"); + Collections.sort(strList, (a, b) -> { + assertEquals("java.lang.String", a.getClass().getName()); + return a.compareTo(b); + }); + assertEquals("[Blue, Green, Red]", Arrays.toString(strList.toArray())); + } + +} diff --git a/core-java-9/README.md b/core-java-9/README.md index 4223e57d4b..a76dcefc69 100644 --- a/core-java-9/README.md +++ b/core-java-9/README.md @@ -25,3 +25,4 @@ - [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue) - [A Guide to Java 9 Modularity](http://www.baeldung.com/java-9-modularity) - [Optional orElse Optional](http://www.baeldung.com/java-optional-or-else-optional) +- [Java 9 java.lang.Module API](http://www.baeldung.com/java-9-module-api) diff --git a/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java b/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java index 0945a21b1b..a96232d66c 100644 --- a/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java +++ b/core-java-io/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java @@ -1,6 +1,7 @@ package org.baeldung.java.io; import org.junit.Test; +import org.junit.Ignore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,6 +106,7 @@ public class JavaReadFromFileUnitTest { } @Test + @Ignore // TODO public void whenReadUTFEncodedFile_thenCorrect() throws IOException { final String expected_value = "青空"; final BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("src/test/resources/test_read7.in"), "UTF-8")); diff --git a/core-java/README.md b/core-java/README.md index 9bc7d9f7ee..fa2d7e4cf0 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -141,6 +141,7 @@ - [Java KeyStore API](http://www.baeldung.com/java-keystore) - [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking) - [Guide to Java Clock Class](http://www.baeldung.com/java-clock) +- [Infinite Loops in Java](http://www.baeldung.com/infinite-loops-java) - [Using Java Assertions](http://www.baeldung.com/java-assert) - [Pass-By-Value as a Parameter Passing Mechanism in Java](http://www.baeldung.com/java-pass-by-value-or-pass-by-reference) - [Check If a String Is Numeric in Java](http://www.baeldung.com/java-check-string-number) @@ -149,5 +150,13 @@ - [NaN in Java](http://www.baeldung.com/java-not-a-number) - [Infinite Loops in Java](http://www.baeldung.com/infinite-loops-java) - [Why Use char[] Array Over a String for Storing Passwords in Java?](http://www.baeldung.com/java-storing-passwords) - - +- [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns) +- [Proxy, Decorator, Adapter and Bridge Patterns](http://www.baeldung.com/java-structural-design-patterns) +- [Singletons in Java](http://www.baeldung.com/java-singleton) +- [Flyweight Pattern in Java](http://www.baeldung.com/java-flyweight) +- [The Observer Pattern in Java](http://www.baeldung.com/java-observer-pattern) +- [Service Locator Pattern](http://www.baeldung.com/java-service-locator-pattern) +- [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join) +- [Guide to the super Java Keyword](http://www.baeldung.com/java-super) +- [Guide to the this Java Keyword](http://www.baeldung.com/java-this) +- [Jagged Arrays In Java](http://www.baeldung.com/java-jagged-arrays) diff --git a/core-java/src/main/java/com/baeldung/linkedlist/LinkedList.java b/core-java/src/main/java/com/baeldung/linkedlist/LinkedList.java deleted file mode 100644 index 12c73f2489..0000000000 --- a/core-java/src/main/java/com/baeldung/linkedlist/LinkedList.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.baeldung.linkedlist; - -/** - * Implementation of a singly linked list. - */ -public class LinkedList { - private Node head; - private Node tail; - - public Node head() { - return head; - } - - public void add(String data) { - Node newNode = new Node(data); - - if (head == null) { - head = newNode; - tail = newNode; - } else { - tail.next = newNode; - tail = newNode; - } - } - - public static class Node { - private Node next; - private String data; - - public Node(String data) { - this.data = data; - } - - public String data() { - return data; - } - - public void setData(String data) { - this.data = data; - } - - public boolean hasNext() { - return next != null; - } - - public Node next() { - return next; - } - - public void setNext(Node next) { - this.next = next; - } - - public String toString() { - return this.data; - } - } -} diff --git a/core-java/src/main/java/com/baeldung/linkedlist/MiddleElementLookup.java b/core-java/src/main/java/com/baeldung/linkedlist/MiddleElementLookup.java index 27684c93d2..4cfa0d411b 100644 --- a/core-java/src/main/java/com/baeldung/linkedlist/MiddleElementLookup.java +++ b/core-java/src/main/java/com/baeldung/linkedlist/MiddleElementLookup.java @@ -1,12 +1,23 @@ package com.baeldung.linkedlist; -import com.baeldung.linkedlist.LinkedList.Node; +import java.util.LinkedList; +import java.util.Optional; + +import com.baeldung.linkedlist.Node; public class MiddleElementLookup { - public static String findMiddleElement(Node head) { + public static Optional findMiddleElementLinkedList(LinkedList linkedList) { + if (linkedList == null || linkedList.isEmpty()) { + return Optional.empty(); + } + + return Optional.ofNullable(linkedList.get((linkedList.size() - 1) / 2)); + } + + public static Optional findMiddleElementFromHead(Node head) { if (head == null) { - return null; + return Optional.empty(); } // calculate the size of the list @@ -23,17 +34,17 @@ public class MiddleElementLookup { current = current.next(); } - return current.data(); + return Optional.ofNullable(current.data()); } - public static String findMiddleElement1PassRecursively(Node head) { + public static Optional findMiddleElementFromHead1PassRecursively(Node head) { if (head == null) { - return null; + return Optional.empty(); } MiddleAuxRecursion middleAux = new MiddleAuxRecursion(); findMiddleRecursively(head, middleAux); - return middleAux.middle.data(); + return Optional.ofNullable(middleAux.middle.data()); } private static void findMiddleRecursively(Node node, MiddleAuxRecursion middleAux) { @@ -53,9 +64,9 @@ public class MiddleElementLookup { middleAux.length--; } - public static String findMiddleElement1PassIteratively(Node head) { + public static Optional findMiddleElementFromHead1PassIteratively(Node head) { if (head == null) { - return null; + return Optional.empty(); } Node slowPointer = head; @@ -68,7 +79,7 @@ public class MiddleElementLookup { slowPointer = slowPointer.next(); } - return slowPointer.data(); + return Optional.ofNullable(slowPointer.data()); } private static class MiddleAuxRecursion { diff --git a/core-java/src/main/java/com/baeldung/linkedlist/Node.java b/core-java/src/main/java/com/baeldung/linkedlist/Node.java new file mode 100644 index 0000000000..daceaffdcd --- /dev/null +++ b/core-java/src/main/java/com/baeldung/linkedlist/Node.java @@ -0,0 +1,34 @@ +package com.baeldung.linkedlist; + +public class Node { + private Node next; + private String data; + + public Node(String data) { + this.data = data; + } + + public String data() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public boolean hasNext() { + return next != null; + } + + public Node next() { + return next; + } + + public void setNext(Node next) { + this.next = next; + } + + public String toString() { + return this.data; + } +} diff --git a/core-java/src/test/java/com/baeldung/array/JaggedArrayUnitTest.java b/core-java/src/test/java/com/baeldung/array/JaggedArrayUnitTest.java index f432436190..a4dd7e25c3 100644 --- a/core-java/src/test/java/com/baeldung/array/JaggedArrayUnitTest.java +++ b/core-java/src/test/java/com/baeldung/array/JaggedArrayUnitTest.java @@ -46,7 +46,7 @@ public class JaggedArrayUnitTest { ByteArrayOutputStream outContent = new ByteArrayOutputStream(); System.setOut(new PrintStream(outContent)); obj.printElements(jaggedArr); - assertEquals("[1, 2]\n[3, 4, 5]\n[6, 7, 8, 9]\n", outContent.toString()); + assertEquals("[1, 2][3, 4, 5][6, 7, 8, 9]", outContent.toString().replace("\r", "").replace("\n", "")); System.setOut(System.out); } diff --git a/core-java/src/test/java/com/baeldung/arrays/ArraysUnitTest.java b/core-java/src/test/java/com/baeldung/arrays/ArraysUnitTest.java new file mode 100644 index 0000000000..9e6d3d6131 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/arrays/ArraysUnitTest.java @@ -0,0 +1,153 @@ +package com.baeldung.arrays; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +public class ArraysUnitTest { + private String[] intro; + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + @Before + public void setup() { + intro = new String[] { "once", "upon", "a", "time" }; + } + + @Test + public void whenCopyOfRange_thenAbridgedArray() { + String[] abridgement = Arrays.copyOfRange(intro, 0, 3); + + assertArrayEquals(new String[] { "once", "upon", "a" }, abridgement); + assertFalse(Arrays.equals(intro, abridgement)); + } + + @Test + public void whenCopyOf_thenNullElement() { + String[] revised = Arrays.copyOf(intro, 3); + String[] expanded = Arrays.copyOf(intro, 5); + + assertArrayEquals(Arrays.copyOfRange(intro, 0, 3), revised); + assertNull(expanded[4]); + } + + @Test + public void whenFill_thenAllMatch() { + String[] stutter = new String[3]; + Arrays.fill(stutter, "once"); + + assertTrue(Stream.of(stutter).allMatch(el -> "once".equals(el))); + } + + @Test + public void whenEqualsContent_thenMatch() { + assertTrue(Arrays.equals(new String[] { "once", "upon", "a", "time" }, intro)); + assertFalse(Arrays.equals(new String[] { "once", "upon", "a", null }, intro)); + } + + @Test + public void whenNestedArrays_thenDeepEqualsPass() { + String[] end = { "the", "end" }; + Object[] story = new Object[] { intro, new String[] { "chapter one", "chapter two" }, end }; + Object[] copy = new Object[] { intro, new String[] { "chapter one", "chapter two" }, end }; + + assertTrue(Arrays.deepEquals(story, copy)); + assertFalse(Arrays.equals(story, copy)); + } + + @Test + public void whenSort_thenArraySorted() { + String[] sorted = Arrays.copyOf(intro, 4); + Arrays.sort(sorted); + + assertArrayEquals(new String[] { "a", "once", "time", "upon" }, sorted); + } + + @Test + public void whenBinarySearch_thenFindElements() { + String[] sorted = Arrays.copyOf(intro, 4); + Arrays.sort(sorted); + int exact = Arrays.binarySearch(sorted, "time"); + int caseInsensitive = Arrays.binarySearch(sorted, "TiMe", String::compareToIgnoreCase); + + assertEquals("time", sorted[exact]); + assertEquals(2, exact); + assertEquals(exact, caseInsensitive); + } + + @Test + public void whenNullElement_thenArraysHashCodeNotEqual() { + int beforeChange = Arrays.hashCode(intro); + int before = intro.hashCode(); + intro[3] = null; + int after = intro.hashCode(); + int afterChange = Arrays.hashCode(intro); + + assertNotEquals(beforeChange, afterChange); + assertEquals(before, after); + } + + @Test + public void whenNestedArrayNullElement_thenEqualsFailDeepHashPass() { + Object[] looping = new Object[] { intro, intro }; + int deepHashBefore = Arrays.deepHashCode(looping); + int hashBefore = Arrays.hashCode(looping); + + intro[3] = null; + + int hashAfter = Arrays.hashCode(looping); + int deepHashAfter = Arrays.deepHashCode(looping); + + assertEquals(hashAfter, hashBefore); + assertNotEquals(deepHashAfter, deepHashBefore); + } + + @Test + public void whenStreamBadIndex_thenException() { + assertEquals(Arrays.stream(intro).count(), 4); + + exception.expect(ArrayIndexOutOfBoundsException.class); + Arrays.stream(intro, 2, 1).count(); + } + + @Test + public void whenSetAllToUpper_thenAppliedToAllElements() { + String[] longAgo = new String[4]; + Arrays.setAll(longAgo, i -> intro[i].toUpperCase()); + + assertArrayEquals(longAgo, new String[] { "ONCE", "UPON", "A", "TIME" }); + } + + @Test + public void whenToString_thenFormattedArrayString() { + assertEquals("[once, upon, a, time]", Arrays.toString(intro)); + } + + @Test + public void whenNestedArrayDeepString_thenFormattedArraysString() { + String[] end = { "the", "end" }; + Object[] story = new Object[] { intro, new String[] { "chapter one", "chapter two" }, end }; + + assertEquals("[[once, upon, a, time], [chapter one, chapter two], [the, end]]", Arrays.deepToString(story)); + } + + @Test + public void whenAsList_thenImmutableArray() { + List rets = Arrays.asList(intro); + + assertTrue(rets.contains("upon")); + assertTrue(rets.contains("time")); + assertEquals(rets.size(), 4); + + exception.expect(UnsupportedOperationException.class); + rets.add("the"); + } +} diff --git a/core-java/src/test/java/com/baeldung/linkedlist/MiddleElementLookupUnitTest.java b/core-java/src/test/java/com/baeldung/linkedlist/MiddleElementLookupUnitTest.java index d456259612..2801bbfc9e 100644 --- a/core-java/src/test/java/com/baeldung/linkedlist/MiddleElementLookupUnitTest.java +++ b/core-java/src/test/java/com/baeldung/linkedlist/MiddleElementLookupUnitTest.java @@ -1,52 +1,97 @@ package com.baeldung.linkedlist; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.LinkedList; import org.junit.Test; public class MiddleElementLookupUnitTest { @Test - public void whenFindingMiddle_thenMiddleFound() { - String middle = MiddleElementLookup.findMiddleElement(createList(5).head()); - assertEquals("3", middle); - - middle = MiddleElementLookup.findMiddleElement(createList(4).head()); - assertEquals("2", middle); + public void whenFindingMiddleLinkedList_thenMiddleFound() { + assertEquals("3", MiddleElementLookup + .findMiddleElementLinkedList(createLinkedList(5)) + .get()); + assertEquals("2", MiddleElementLookup + .findMiddleElementLinkedList(createLinkedList(4)) + .get()); } @Test - public void whenFindingMiddle1PassRecursively_thenMiddleFound() { - String middle = MiddleElementLookup.findMiddleElement1PassRecursively(createList(5).head()); - assertEquals("3", middle); - - middle = MiddleElementLookup.findMiddleElement1PassRecursively(createList(4).head()); - assertEquals("2", middle); + public void whenFindingMiddleFromHead_thenMiddleFound() { + assertEquals("3", MiddleElementLookup + .findMiddleElementFromHead(createNodesList(5)) + .get()); + assertEquals("2", MiddleElementLookup + .findMiddleElementFromHead(createNodesList(4)) + .get()); } @Test - public void whenFindingMiddle1PassIteratively_thenMiddleFound() { - String middle = MiddleElementLookup.findMiddleElement1PassIteratively(createList(5).head()); - assertEquals("3", middle); - - middle = MiddleElementLookup.findMiddleElement1PassIteratively(createList(4).head()); - assertEquals("2", middle); + public void whenFindingMiddleFromHead1PassRecursively_thenMiddleFound() { + assertEquals("3", MiddleElementLookup + .findMiddleElementFromHead1PassRecursively(createNodesList(5)) + .get()); + assertEquals("2", MiddleElementLookup + .findMiddleElementFromHead1PassRecursively(createNodesList(4)) + .get()); } @Test - public void whenListEmptyOrNull_thenMiddleNull() { - String middle = MiddleElementLookup.findMiddleElement(null); - assertEquals(null, middle); - - middle = MiddleElementLookup.findMiddleElement1PassIteratively(null); - assertEquals(null, middle); - - middle = MiddleElementLookup.findMiddleElement1PassRecursively(null); - assertEquals(null, middle); + public void whenFindingMiddleFromHead1PassIteratively_thenMiddleFound() { + assertEquals("3", MiddleElementLookup + .findMiddleElementFromHead1PassIteratively(createNodesList(5)) + .get()); + assertEquals("2", MiddleElementLookup + .findMiddleElementFromHead1PassIteratively(createNodesList(4)) + .get()); } - private static LinkedList createList(int n) { - LinkedList list = new LinkedList(); + @Test + public void whenListEmptyOrNull_thenMiddleNotFound() { + // null list + assertFalse(MiddleElementLookup + .findMiddleElementLinkedList(null) + .isPresent()); + assertFalse(MiddleElementLookup + .findMiddleElementFromHead(null) + .isPresent()); + assertFalse(MiddleElementLookup + .findMiddleElementFromHead1PassIteratively(null) + .isPresent()); + assertFalse(MiddleElementLookup + .findMiddleElementFromHead1PassRecursively(null) + .isPresent()); + + // empty LinkedList + assertFalse(MiddleElementLookup + .findMiddleElementLinkedList(new LinkedList<>()) + .isPresent()); + + // LinkedList with nulls + LinkedList nullsList = new LinkedList<>(); + nullsList.add(null); + nullsList.add(null); + assertFalse(MiddleElementLookup + .findMiddleElementLinkedList(nullsList) + .isPresent()); + + // nodes with null values + assertFalse(MiddleElementLookup + .findMiddleElementFromHead(new Node(null)) + .isPresent()); + assertFalse(MiddleElementLookup + .findMiddleElementFromHead1PassIteratively(new Node(null)) + .isPresent()); + assertFalse(MiddleElementLookup + .findMiddleElementFromHead1PassRecursively(new Node(null)) + .isPresent()); + } + + private static LinkedList createLinkedList(int n) { + LinkedList list = new LinkedList<>(); for (int i = 1; i <= n; i++) { list.add(String.valueOf(i)); @@ -55,4 +100,17 @@ public class MiddleElementLookupUnitTest { return list; } + private static Node createNodesList(int n) { + Node head = new Node("1"); + Node current = head; + + for (int i = 2; i <= n; i++) { + Node newNode = new Node(String.valueOf(i)); + current.setNext(newNode); + current = newNode; + } + + return head; + } + } diff --git a/core-java/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java b/core-java/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java index fe2747bcee..04d2886a82 100644 --- a/core-java/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java +++ b/core-java/src/test/java/com/baeldung/money/JavaMoneyUnitManualTest.java @@ -179,7 +179,7 @@ public class JavaMoneyUnitManualTest { MonetaryAmountFormat customFormat = MonetaryFormats.getAmountFormat(AmountFormatQueryBuilder .of(Locale.US) .set(CurrencyStyle.NAME) - .set("pattern", "00000.00 �") + .set("pattern", "00000.00 US Dollar") .build()); String customFormatted = customFormat.format(oneDollar); diff --git a/core-java/src/test/java/com/baeldung/scripting/NashornUnitTest.java b/core-java/src/test/java/com/baeldung/scripting/NashornUnitTest.java index 7f165cec86..9abe8a927c 100644 --- a/core-java/src/test/java/com/baeldung/scripting/NashornUnitTest.java +++ b/core-java/src/test/java/com/baeldung/scripting/NashornUnitTest.java @@ -104,7 +104,7 @@ public class NashornUnitTest { public void loadExamples() throws ScriptException { Object loadResult = engine.eval("load('classpath:js/script.js');" + "increment(5)"); - Assert.assertEquals(6.0, loadResult); + Assert.assertEquals(6, ((Double) loadResult).intValue()); Object math = engine.eval("var math = loadWithNewGlobal('classpath:js/math_module.js');" + "math.increment(5);"); diff --git a/core-kotlin/src/main/kotlin/com/baeldung/enums/CardType.kt b/core-kotlin/src/main/kotlin/com/baeldung/enums/CardType.kt index ae0c707289..69cfce5601 100644 --- a/core-kotlin/src/main/kotlin/com/baeldung/enums/CardType.kt +++ b/core-kotlin/src/main/kotlin/com/baeldung/enums/CardType.kt @@ -2,32 +2,22 @@ package com.baeldung.enums enum class CardType(val color: String) : ICardLimit { SILVER("gray") { - override fun getCreditLimit(): Int { - return 100000 - } - - override fun calculateCashbackPercent(): Float { - return 0.25f - } + override fun getCreditLimit() = 100000 + override fun calculateCashbackPercent() = 0.25f }, GOLD("yellow") { - override fun getCreditLimit(): Int { - return 200000 - } - - override fun calculateCashbackPercent(): Float { - return 0.5f - } + override fun getCreditLimit() = 200000 + override fun calculateCashbackPercent(): Float = 0.5f }, PLATINUM("black") { - override fun getCreditLimit(): Int { - return 300000 - } - - override fun calculateCashbackPercent(): Float { - return 0.75f - } + override fun getCreditLimit() = 300000 + override fun calculateCashbackPercent() = 0.75f }; + companion object { + fun getCardTypeByColor(color: String) = values().firstOrNull { it.color == color } + fun getCardTypeByName(name: String) = valueOf(name.toUpperCase()) + } + abstract fun calculateCashbackPercent(): Float } \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/enums/CardTypeHelper.kt b/core-kotlin/src/main/kotlin/com/baeldung/enums/CardTypeHelper.kt deleted file mode 100644 index 29982192bb..0000000000 --- a/core-kotlin/src/main/kotlin/com/baeldung/enums/CardTypeHelper.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.enums - -class CardTypeHelper { - fun getCardTypeByColor(color: String): CardType? { - for (cardType in CardType.values()) { - if (cardType.color.equals(color)) { - return cardType; - } - } - return null - } - - fun getCardTypeByName(name: String): CardType { - return CardType.valueOf(name.toUpperCase()) - } -} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/enums/CardTypeHelperUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/enums/CardTypeHelperUnitTest.kt deleted file mode 100644 index 8fcd281784..0000000000 --- a/core-kotlin/src/test/kotlin/com/baeldung/enums/CardTypeHelperUnitTest.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.baeldung.enums - -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -internal class CardTypeHelperUnitTest { - - @Test - fun whenGetCardTypeByColor_thenSilverCardType() { - val cardTypeHelper = CardTypeHelper() - Assertions.assertEquals(CardType.SILVER, cardTypeHelper.getCardTypeByColor("gray")) - } - - @Test - fun whenGetCardTypeByColor_thenGoldCardType() { - val cardTypeHelper = CardTypeHelper() - Assertions.assertEquals(CardType.GOLD, cardTypeHelper.getCardTypeByColor("yellow")) - } - - @Test - fun whenGetCardTypeByColor_thenPlatinumCardType() { - val cardTypeHelper = CardTypeHelper() - Assertions.assertEquals(CardType.PLATINUM, cardTypeHelper.getCardTypeByColor("black")) - } - - @Test - fun whenGetCardTypeByName_thenSilverCardType() { - val cardTypeHelper = CardTypeHelper() - Assertions.assertEquals(CardType.SILVER, cardTypeHelper.getCardTypeByName("silver")) - } - - @Test - fun whenGetCardTypeByName_thenGoldCardType() { - val cardTypeHelper = CardTypeHelper() - Assertions.assertEquals(CardType.GOLD, cardTypeHelper.getCardTypeByName("gold")) - } - - @Test - fun whenGetCardTypeByName_thenPlatinumCardType() { - val cardTypeHelper = CardTypeHelper() - Assertions.assertEquals(CardType.PLATINUM, cardTypeHelper.getCardTypeByName("platinum")) - } -} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/enums/CardTypeUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/enums/CardTypeUnitTest.kt index 0e74e1cf56..525faebd55 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/enums/CardTypeUnitTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/enums/CardTypeUnitTest.kt @@ -1,5 +1,6 @@ package com.baeldung.enums +import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -49,4 +50,35 @@ internal class CardTypeUnitTest { fun givenPlatinumCardType_whenCheckColor_thenReturnColor() { assertEquals("black", CardType.PLATINUM.color) } + + @Test + fun whenGetCardTypeByColor_thenSilverCardType() { + Assertions.assertEquals(CardType.SILVER, CardType.getCardTypeByColor("gray")) + } + + @Test + fun whenGetCardTypeByColor_thenGoldCardType() { + Assertions.assertEquals(CardType.GOLD, CardType.getCardTypeByColor("yellow")) + } + + @Test + fun whenGetCardTypeByColor_thenPlatinumCardType() { + Assertions.assertEquals(CardType.PLATINUM, CardType.getCardTypeByColor("black")) + } + + @Test + fun whenGetCardTypeByName_thenSilverCardType() { + Assertions.assertEquals(CardType.SILVER, CardType.getCardTypeByName("silver")) + } + + @Test + fun whenGetCardTypeByName_thenGoldCardType() { + Assertions.assertEquals(CardType.GOLD, CardType.getCardTypeByName("gold")) + } + + @Test + fun whenGetCardTypeByName_thenPlatinumCardType() { + Assertions.assertEquals(CardType.PLATINUM, CardType.getCardTypeByName("platinum")) + } + } diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java index e708922988..3100f0c70b 100644 --- a/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java @@ -5,6 +5,7 @@ import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.couchbase.client.java.Bucket; @@ -18,6 +19,11 @@ public class ClusterServiceImpl implements ClusterService { private Cluster cluster; private Map buckets = new ConcurrentHashMap<>(); + + @Autowired + public ClusterServiceImpl(Cluster cluster) { + this.cluster = cluster; + } @PostConstruct private void init() { diff --git a/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java index 459585d995..75a196ff5d 100644 --- a/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java +++ b/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java @@ -18,6 +18,7 @@ public class TutorialBucketService extends AbstractBucketService { @Autowired public TutorialBucketService(ClusterService clusterService) { super(clusterService); + openBucket(); } @Override diff --git a/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTestConfig.java b/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTestConfig.java new file mode 100644 index 0000000000..9e650752d2 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTestConfig.java @@ -0,0 +1,24 @@ +package com.baeldung.couchbase.async.person; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.CouchbaseCluster; +import com.couchbase.client.java.env.CouchbaseEnvironment; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; + +@Configuration +@ComponentScan(basePackages = {"com.baeldung.couchbase.async.service", "com.baeldung.couchbase.n1ql"}) +public class PersonCrudServiceIntegrationTestConfig { + + @Bean + public Cluster cluster() { + CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder() + .connectTimeout(60000) + .build(); + return CouchbaseCluster.create(env, "127.0.0.1"); + } + +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceLiveTest.java similarity index 90% rename from couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceLiveTest.java index 565aaed5da..267071ab35 100644 --- a/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java +++ b/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceLiveTest.java @@ -1,27 +1,31 @@ package com.baeldung.couchbase.async.person; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; import java.util.UUID; -import javax.annotation.PostConstruct; - import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.baeldung.couchbase.async.AsyncIntegrationTest; -import com.baeldung.couchbase.async.person.Person; -import com.baeldung.couchbase.async.person.PersonCrudService; -import com.baeldung.couchbase.async.person.PersonDocumentConverter; import com.baeldung.couchbase.async.service.BucketService; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.document.JsonDocument; -public class PersonCrudServiceIntegrationTest extends AsyncIntegrationTest { +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {PersonCrudServiceIntegrationTestConfig.class}) +public class PersonCrudServiceLiveTest extends AsyncIntegrationTest { @Autowired private PersonCrudService personService; @@ -35,8 +39,8 @@ public class PersonCrudServiceIntegrationTest extends AsyncIntegrationTest { private Bucket bucket; - @PostConstruct - private void init() { + @Before + public void init() { bucket = bucketService.getBucket(); } diff --git a/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceLiveTest.java similarity index 94% rename from couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceLiveTest.java index d0db5d37a3..5f478ae788 100644 --- a/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java +++ b/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceLiveTest.java @@ -18,7 +18,7 @@ import com.couchbase.client.java.Bucket; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { AsyncIntegrationTestConfig.class }) @TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) -public class ClusterServiceIntegrationTest extends AsyncIntegrationTest { +public class ClusterServiceLiveTest extends AsyncIntegrationTest { @Autowired private ClusterService couchbaseService; diff --git a/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceLiveTest.java similarity index 98% rename from couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceLiveTest.java index 00d462e32a..d260795ed3 100644 --- a/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java +++ b/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceLiveTest.java @@ -14,8 +14,8 @@ import com.couchbase.client.java.document.JsonDocument; import com.couchbase.client.java.view.ViewResult; import com.couchbase.client.java.view.ViewRow; -public class StudentGradeServiceIntegrationTest { - private static final Logger logger = LoggerFactory.getLogger(StudentGradeServiceIntegrationTest.class); +public class StudentGradeServiceLiveTest { + private static final Logger logger = LoggerFactory.getLogger(StudentGradeServiceLiveTest.class); static StudentGradeService studentGradeService; static Set gradeIds = new HashSet<>(); diff --git a/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLLiveTest.java similarity index 97% rename from couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLLiveTest.java index 8112d7d222..602bb5b8a5 100644 --- a/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java +++ b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLLiveTest.java @@ -1,5 +1,23 @@ package com.baeldung.couchbase.n1ql; +import static com.baeldung.couchbase.n1ql.CodeSnippets.extractJsonResult; +import static com.couchbase.client.java.query.Select.select; +import static com.couchbase.client.java.query.dsl.Expression.i; +import static com.couchbase.client.java.query.dsl.Expression.s; +import static com.couchbase.client.java.query.dsl.Expression.x; +import static org.junit.Assert.assertNotNull; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; import com.couchbase.client.java.document.JsonDocument; @@ -10,28 +28,13 @@ import com.couchbase.client.java.query.N1qlQueryResult; import com.couchbase.client.java.query.N1qlQueryRow; import com.couchbase.client.java.query.Statement; import com.fasterxml.jackson.databind.JsonNode; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + import rx.Observable; -import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static com.baeldung.couchbase.n1ql.CodeSnippets.extractJsonResult; -import static com.couchbase.client.java.query.Select.select; -import static com.couchbase.client.java.query.dsl.Expression.*; -import static org.junit.Assert.assertNotNull; - @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { IntegrationTestConfig.class }) -public class N1QLIntegrationTest { +public class N1QLLiveTest { @Autowired diff --git a/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceLiveTest.java similarity index 97% rename from couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceLiveTest.java index ec15be1acc..493b326d49 100644 --- a/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java +++ b/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceLiveTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import com.baeldung.couchbase.spring.IntegrationTest; -public class PersonCrudServiceIntegrationTest extends IntegrationTest { +public class PersonCrudServiceLiveTest extends IntegrationTest { private static final String CLARK_KENT = "Clark Kent"; private static final String SMALLVILLE = "Smallville"; diff --git a/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceLiveTest.java similarity index 94% rename from couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceLiveTest.java index ead247dfbc..7a89a208f7 100644 --- a/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java +++ b/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceLiveTest.java @@ -17,7 +17,7 @@ import com.couchbase.client.java.Bucket; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { IntegrationTestConfig.class }) @TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) -public class ClusterServiceIntegrationTest extends IntegrationTest { +public class ClusterServiceLiveTest extends IntegrationTest { @Autowired private ClusterService couchbaseService; diff --git a/ejb/ejb-client/pom.xml b/ejb/ejb-client/pom.xml index 83dd0aef30..88116f8003 100755 --- a/ejb/ejb-client/pom.xml +++ b/ejb/ejb-client/pom.xml @@ -3,7 +3,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 ejb-client - EJB3 Client Maven EJB3 Client Maven diff --git a/ethereumj/README.md b/ethereumj/README.md index 5a0be0bd16..320ae8c9f8 100644 --- a/ethereumj/README.md +++ b/ethereumj/README.md @@ -3,3 +3,4 @@ ### Relevant Articles: - [Introduction to EthereumJ](http://www.baeldung.com/ethereumj) - [Creating and Deploying Smart Contracts with Solidity](http://www.baeldung.com/smart-contracts-ethereum-solidity) +- [Lightweight Ethereum Clients Using Web3j](http://www.baeldung.com/web3j) diff --git a/ethereumj/pom.xml b/ethereumj/pom.xml index 611b7b09eb..6917505f1b 100644 --- a/ethereumj/pom.xml +++ b/ethereumj/pom.xml @@ -10,10 +10,10 @@ ethereumj - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/flips/pom.xml b/flips/pom.xml index be9f584114..34cbab7035 100644 --- a/flips/pom.xml +++ b/flips/pom.xml @@ -8,10 +8,10 @@ flips - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/flyway/pom.xml b/flyway/pom.xml index 3637f1de28..018f9b7f86 100644 --- a/flyway/pom.xml +++ b/flyway/pom.xml @@ -8,10 +8,10 @@ Flyway Callbacks Demo - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/grpc/pom.xml b/grpc/pom.xml index ad563f16fd..fb8312e8df 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -5,8 +5,6 @@ grpc-demo 0.0.1-SNAPSHOT jar - grpc-demo - http://maven.apache.org com.baeldung diff --git a/gson/README.md b/gson/README.md index 60c80477b1..bedfbd206c 100644 --- a/gson/README.md +++ b/gson/README.md @@ -6,3 +6,4 @@ ### Relevant Articles: - [Gson Deserialization Cookbook](http://www.baeldung.com/gson-deserialization-guide) - [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson) +- [Exclude Fields from Serialization in Gson](http://www.baeldung.com/gson-exclude-fields-serialization) diff --git a/guest/spring-boot-app/WebContent/META-INF/MANIFEST.MF b/guest/spring-boot-app/WebContent/META-INF/MANIFEST.MF index 254272e1c0..e3c07ab38a 100644 --- a/guest/spring-boot-app/WebContent/META-INF/MANIFEST.MF +++ b/guest/spring-boot-app/WebContent/META-INF/MANIFEST.MF @@ -1,3 +1,2 @@ Manifest-Version: 1.0 Class-Path: - diff --git a/guest/spring-boot-app/docker/Dockerfile b/guest/spring-boot-app/docker/Dockerfile new file mode 100644 index 0000000000..211e8927a3 --- /dev/null +++ b/guest/spring-boot-app/docker/Dockerfile @@ -0,0 +1,16 @@ +# Alpine Linux with OpenJDK JRE +FROM openjdk:8-jre-alpine +RUN apk add --no-cache bash + +# copy fat WAR +COPY spring-boot-app-0.0.1-SNAPSHOT.war /app.war + +# copy fat WAR +COPY logback.xml /logback.xml + +COPY run.sh /run.sh + +# runs application +#CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=default", "-Dlogging.config=/logback.xml", "/app.war"] + +ENTRYPOINT ["/run.sh"] diff --git a/guest/spring-boot-app/docker/logback.xml b/guest/spring-boot-app/docker/logback.xml new file mode 100644 index 0000000000..7e03ddc827 --- /dev/null +++ b/guest/spring-boot-app/docker/logback.xml @@ -0,0 +1,15 @@ + + + + + /var/log/Application/application.log + true + + %-7d{yyyy-MM-dd HH:mm:ss:SSS} %m%n + + + + + + + diff --git a/guest/spring-boot-app/docker/run.sh b/guest/spring-boot-app/docker/run.sh new file mode 100755 index 0000000000..aeecc29371 --- /dev/null +++ b/guest/spring-boot-app/docker/run.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +java -Dspring.profiles.active=$1 -Dlogging.config=/logback.xml -jar /app.war + diff --git a/guest/spring-boot-app/pom.xml b/guest/spring-boot-app/pom.xml index ba57bbd5c5..c02eef7ef3 100644 --- a/guest/spring-boot-app/pom.xml +++ b/guest/spring-boot-app/pom.xml @@ -51,6 +51,22 @@ WebContent + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + com.stackify.Application + ${project.basedir}/docker + + + + + @@ -58,4 +74,4 @@ 8.0.43 - \ No newline at end of file + diff --git a/guest/spring-mvc/pom.xml b/guest/spring-mvc/pom.xml index 169b216ff9..da4d27b14d 100644 --- a/guest/spring-mvc/pom.xml +++ b/guest/spring-mvc/pom.xml @@ -27,28 +27,6 @@ - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - UTF-8 UTF-8 diff --git a/guest/spring-security/pom.xml b/guest/spring-security/pom.xml index 16e946d108..793df750de 100644 --- a/guest/spring-security/pom.xml +++ b/guest/spring-security/pom.xml @@ -45,28 +45,6 @@ - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - UTF-8 UTF-8 diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index e8fdabebbc..23d7d2e201 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -1,5 +1,7 @@ package com.baeldung.hibernate; +import com.baeldung.hibernate.optimisticlocking.OptimisticLockingCourse; +import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent; import com.baeldung.hibernate.pessimisticlocking.Individual; import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingCourse; import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingEmployee; @@ -70,6 +72,8 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(PessimisticLockingCourse.class); metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Customer.class); metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Address.class); + metadataSources.addAnnotatedClass(OptimisticLockingCourse.class); + metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); Metadata metadata = metadataSources.buildMetadata(); return metadata.getSessionFactoryBuilder() diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java new file mode 100644 index 0000000000..f7b8e6bf6d --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/application/Application.java @@ -0,0 +1,34 @@ +package com.baeldung.hibernate.jpabootstrap.application; + +import com.baeldung.hibernate.jpabootstrap.config.JpaEntityManagerFactory; +import com.baeldung.hibernate.jpabootstrap.entities.User; +import javax.persistence.EntityManager; + +public class Application { + + public static void main(String[] args) { + EntityManager entityManager = getJpaEntityManager(); + User user = entityManager.find(User.class, 1); + System.out.println(user); + entityManager.getTransaction().begin(); + user.setName("John"); + user.setEmail("john@domain.com"); + entityManager.merge(user); + entityManager.getTransaction().commit(); + entityManager.getTransaction().begin(); + entityManager.persist(new User("Monica", "monica@domain.com")); + entityManager.getTransaction().commit(); + + // additional CRUD operations + + } + + private static class EntityManagerHolder { + private static final EntityManager ENTITY_MANAGER = new JpaEntityManagerFactory( + new Class[]{User.class}).getEntityManager(); + } + + public static EntityManager getJpaEntityManager() { + return EntityManagerHolder.ENTITY_MANAGER; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java new file mode 100644 index 0000000000..3852b44b64 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/config/HibernatePersistenceUnitInfo.java @@ -0,0 +1,131 @@ +package com.baeldung.hibernate.jpabootstrap.config; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import javax.sql.DataSource; +import javax.persistence.SharedCacheMode; +import javax.persistence.ValidationMode; +import javax.persistence.spi.ClassTransformer; +import javax.persistence.spi.PersistenceUnitInfo; +import javax.persistence.spi.PersistenceUnitTransactionType; +import org.hibernate.jpa.HibernatePersistenceProvider; + +public class HibernatePersistenceUnitInfo implements PersistenceUnitInfo { + + public static final String JPA_VERSION = "2.1"; + private final String persistenceUnitName; + private PersistenceUnitTransactionType transactionType = PersistenceUnitTransactionType.RESOURCE_LOCAL; + private final List managedClassNames; + private final List mappingFileNames = new ArrayList<>(); + private final Properties properties; + private DataSource jtaDataSource; + private DataSource nonjtaDataSource; + private final List transformers = new ArrayList<>(); + + public HibernatePersistenceUnitInfo(String persistenceUnitName, List managedClassNames, Properties properties) { + this.persistenceUnitName = persistenceUnitName; + this.managedClassNames = managedClassNames; + this.properties = properties; + } + + @Override + public String getPersistenceUnitName() { + return persistenceUnitName; + } + + @Override + public String getPersistenceProviderClassName() { + return HibernatePersistenceProvider.class.getName(); + } + + @Override + public PersistenceUnitTransactionType getTransactionType() { + return transactionType; + } + + public HibernatePersistenceUnitInfo setJtaDataSource(DataSource jtaDataSource) { + this.jtaDataSource = jtaDataSource; + this.nonjtaDataSource = null; + transactionType = PersistenceUnitTransactionType.JTA; + return this; + } + + @Override + public DataSource getJtaDataSource() { + return jtaDataSource; + } + + public HibernatePersistenceUnitInfo setNonJtaDataSource(DataSource nonJtaDataSource) { + this.nonjtaDataSource = nonJtaDataSource; + this.jtaDataSource = null; + transactionType = PersistenceUnitTransactionType.RESOURCE_LOCAL; + return this; + } + + @Override + public DataSource getNonJtaDataSource() { + return nonjtaDataSource; + } + + @Override + public List getMappingFileNames() { + return mappingFileNames; + } + + @Override + public List getJarFileUrls() { + return Collections.emptyList(); + } + + @Override + public URL getPersistenceUnitRootUrl() { + return null; + } + + @Override + public List getManagedClassNames() { + return managedClassNames; + } + + @Override + public boolean excludeUnlistedClasses() { + return false; + } + + @Override + public SharedCacheMode getSharedCacheMode() { + return SharedCacheMode.UNSPECIFIED; + } + + @Override + public ValidationMode getValidationMode() { + return ValidationMode.AUTO; + } + + public Properties getProperties() { + return properties; + } + + @Override + public String getPersistenceXMLSchemaVersion() { + return JPA_VERSION; + } + + @Override + public ClassLoader getClassLoader() { + return Thread.currentThread().getContextClassLoader(); + } + + @Override + public void addTransformer(ClassTransformer transformer) { + transformers.add(transformer); + } + + @Override + public ClassLoader getNewTempClassLoader() { + return null; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java new file mode 100644 index 0000000000..bc1932af6f --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/config/JpaEntityManagerFactory.java @@ -0,0 +1,69 @@ +package com.baeldung.hibernate.jpabootstrap.config; + +import com.mysql.cj.jdbc.MysqlDataSource; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; +import javax.persistence.EntityManager; +import javax.sql.DataSource; +import javax.persistence.EntityManagerFactory; +import javax.persistence.spi.PersistenceUnitInfo; +import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; +import org.hibernate.jpa.boot.internal.PersistenceUnitInfoDescriptor; + +public class JpaEntityManagerFactory { + + private final String DB_URL = "jdbc:mysql://databaseurl"; + private final String DB_USER_NAME = "username"; + private final String DB_PASSWORD = "password"; + private final Class[] entityClasses; + + public JpaEntityManagerFactory(Class[] entityClasses) { + this.entityClasses = entityClasses; + } + + public EntityManager getEntityManager() { + return getEntityManagerFactory().createEntityManager(); + } + + protected EntityManagerFactory getEntityManagerFactory() { + PersistenceUnitInfo persistenceUnitInfo = getPersistenceUnitInfo(getClass().getSimpleName()); + Map configuration = new HashMap<>(); + return new EntityManagerFactoryBuilderImpl(new PersistenceUnitInfoDescriptor(persistenceUnitInfo), configuration) + .build(); + } + + protected HibernatePersistenceUnitInfo getPersistenceUnitInfo(String name) { + return new HibernatePersistenceUnitInfo(name, getEntityClassNames(), getProperties()); + } + + protected List getEntityClassNames() { + return Arrays.asList(getEntities()) + .stream() + .map(Class::getName) + .collect(Collectors.toList()); + } + + protected Properties getProperties() { + Properties properties = new Properties(); + properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); + properties.put("hibernate.id.new_generator_mappings", false); + properties.put("hibernate.connection.datasource", getMysqlDataSource()); + return properties; + } + + protected Class[] getEntities() { + return entityClasses; + } + + protected DataSource getMysqlDataSource() { + MysqlDataSource mysqlDataSource = new MysqlDataSource(); + mysqlDataSource.setURL(DB_URL); + mysqlDataSource.setUser(DB_USER_NAME); + mysqlDataSource.setPassword(DB_PASSWORD); + return mysqlDataSource; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java new file mode 100644 index 0000000000..86ca1dfa19 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/jpabootstrap/entities/User.java @@ -0,0 +1,45 @@ +package com.baeldung.hibernate.jpabootstrap.entities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + private String name; + private String email; + + public User(){} + + public User(String name, String email) { + this.name = name; + this.email = email; + } + + public void setName(String name) { + this.name = name; + } + + public void setEmail(String email) { + this.email = email; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java b/hibernate5/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java new file mode 100644 index 0000000000..1af3e3e21b --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingCourse.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.optimisticlocking; + +import javax.persistence.*; + +@Entity +public class OptimisticLockingCourse { + + @Id + private Long id; + + private String name; + + @ManyToOne + @JoinTable(name = "optimistic_student_course") + private OptimisticLockingStudent student; + + public OptimisticLockingCourse(Long id, String name) { + this.id = id; + this.name = name; + } + + public OptimisticLockingCourse() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public OptimisticLockingStudent getStudent() { + return student; + } + + public void setStudent(OptimisticLockingStudent student) { + this.student = student; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java b/hibernate5/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java new file mode 100644 index 0000000000..b79212ae8d --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingStudent.java @@ -0,0 +1,70 @@ +package com.baeldung.hibernate.optimisticlocking; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class OptimisticLockingStudent { + + @Id + private Long id; + + private String name; + + private String lastName; + @Version + private Integer version; + + @OneToMany(mappedBy = "student") + private List courses; + + public OptimisticLockingStudent(Long id, String name, String lastName, List courses) { + this.id = id; + this.name = name; + this.lastName = lastName; + this.courses = courses; + } + + public OptimisticLockingStudent() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List getCourses() { + return courses; + } + + public void setCourses(List courses) { + this.courses = courses; + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java new file mode 100644 index 0000000000..68b51764e4 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java @@ -0,0 +1,134 @@ +package com.baeldung.hibernate.optimisticlocking; + +import com.baeldung.hibernate.HibernateUtil; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.LockModeType; +import javax.persistence.OptimisticLockException; +import java.io.IOException; +import java.util.Arrays; + +public class OptimisticLockingIntegrationTest { + + @Before + public void setUp() throws IOException { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + OptimisticLockingCourse course = new OptimisticLockingCourse(1L, "MATH"); + OptimisticLockingStudent student = new OptimisticLockingStudent(1L, "John", "Doe", Arrays.asList(course)); + course.setStudent(student); + entityManager.persist(course); + entityManager.persist(student); + entityManager.getTransaction() + .commit(); + entityManager.close(); + } + + @After + public void clean() throws IOException { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + OptimisticLockingCourse course = entityManager.find(OptimisticLockingCourse.class, 1L); + OptimisticLockingStudent student = entityManager.find(OptimisticLockingStudent.class, 1L); + entityManager.remove(course); + entityManager.remove(student); + entityManager.getTransaction() + .commit(); + entityManager.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntities_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntitiesWithLockByFindMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L, LockModeType.OPTIMISTIC); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L, LockModeType.OPTIMISTIC_FORCE_INCREMENT); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntitiesWithLockByRefreshMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L); + em.refresh(student, LockModeType.OPTIMISTIC); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L); + em.refresh(student, LockModeType.OPTIMISTIC_FORCE_INCREMENT); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + @Test(expected = OptimisticLockException.class) + public void givenVersionedEntitiesWithLockByLockMethod_whenConcurrentUpdate_thenOptimisticLockException() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student = em.find(OptimisticLockingStudent.class, 1L); + em.lock(student, LockModeType.OPTIMISTIC); + + EntityManager em2 = getEntityManagerWithOpenTransaction(); + OptimisticLockingStudent student2 = em2.find(OptimisticLockingStudent.class, 1L); + em.lock(student, LockModeType.OPTIMISTIC_FORCE_INCREMENT); + student2.setName("RICHARD"); + em2.persist(student2); + em2.getTransaction() + .commit(); + em2.close(); + + student.setName("JOHN"); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + } + + protected static EntityManager getEntityManagerWithOpenTransaction() throws IOException { + String propertyFileName = "hibernate-pessimistic-locking.properties"; + EntityManager entityManager = HibernateUtil.getSessionFactory(propertyFileName) + .openSession(); + entityManager.getTransaction() + .begin(); + + return entityManager; + } +} diff --git a/hystrix/pom.xml b/hystrix/pom.xml index 8e4a9b28b7..b17ca2bfd9 100644 --- a/hystrix/pom.xml +++ b/hystrix/pom.xml @@ -6,10 +6,10 @@ hystrix - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/java-websocket/pom.xml b/java-websocket/pom.xml index 461182e504..85078bd696 100644 --- a/java-websocket/pom.xml +++ b/java-websocket/pom.xml @@ -5,8 +5,6 @@ java-websocket war 0.0.1-SNAPSHOT - java-websocket Maven Webapp - http://maven.apache.org com.baeldung diff --git a/javax-servlets/README.md b/javax-servlets/README.md index ef8ec168cf..55ca1116aa 100644 --- a/javax-servlets/README.md +++ b/javax-servlets/README.md @@ -3,3 +3,5 @@ - [An MVC Example with Servlets and JSP](http://www.baeldung.com/mvc-servlet-jsp) - [Handling Cookies and a Session in a Java Servlet](http://www.baeldung.com/java-servlet-cookies-session) - [Uploading Files with Servlets and JSP](http://www.baeldung.com/upload-file-servlet) +- [Example of Downloading File in a Servlet](http://www.baeldung.com/servlet-download-file) +- [Returning a JSON Response from a Servlet](http://www.baeldung.com/servlet-json-response) diff --git a/javax-servlets/src/main/java/com/baeldung/model/Employee.java b/javax-servlets/src/main/java/com/baeldung/model/Employee.java index 9a85a69fff..698a598962 100644 --- a/javax-servlets/src/main/java/com/baeldung/model/Employee.java +++ b/javax-servlets/src/main/java/com/baeldung/model/Employee.java @@ -5,9 +5,9 @@ public class Employee { private int id; private String name; private String department; - private Double salary; + private long salary; - public Employee(int id, String name, String department, Double salary) { + public Employee(int id, String name, String department, long salary) { super(); this.id = id; this.name = name; @@ -61,11 +61,11 @@ public class Employee { this.department = department; } - public Double getSalary() { + public long getSalary() { return salary; } - public void setSalary(Double salary) { + public void setSalary(long salary) { this.salary = salary; } diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/EmployeeServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/EmployeeServlet.java index ea82ca5055..dbc1a010f7 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/EmployeeServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/EmployeeServlet.java @@ -14,18 +14,15 @@ import com.google.gson.Gson; @WebServlet(name = "EmployeeServlet", urlPatterns = "/employeeServlet") public class EmployeeServlet extends HttpServlet { + + private Gson gson = new Gson(); @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - int id = Integer.parseInt(request.getParameter("id")); - String name = request.getParameter("name"); - String department = request.getParameter("department"); - Double salary = Double.parseDouble(request.getParameter("salary")); - - Employee employee = new Employee(id, name, department, salary); - String employeeJsonString = new Gson().toJson(employee); + Employee employee = new Employee(1, "Karan", "IT", 5000); + String employeeJsonString = this.gson.toJson(employee); PrintWriter out = response.getWriter(); response.setContentType("application/json"); diff --git a/javax-servlets/src/test/java/com/baeldung/servlets/EmployeeServletIntegrationTest.java b/javax-servlets/src/test/java/com/baeldung/servlets/EmployeeServletIntegrationTest.java index c96ad0a858..4fe4908075 100644 --- a/javax-servlets/src/test/java/com/baeldung/servlets/EmployeeServletIntegrationTest.java +++ b/javax-servlets/src/test/java/com/baeldung/servlets/EmployeeServletIntegrationTest.java @@ -36,21 +36,15 @@ public class EmployeeServletIntegrationTest { int id = 1; String name = "Karan Khanna"; String department = "IT"; - Double salary = 5000.0; + long salary = 5000; employee = new Employee(id, name, department, salary); - //when - when(httpServletRequest.getParameter("id")).thenReturn(String.valueOf(id)); - when(httpServletRequest.getParameter("name")).thenReturn(name); - when(httpServletRequest.getParameter("department")).thenReturn(department); - when(httpServletRequest.getParameter("salary")).thenReturn(String.valueOf(salary)); - StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); when(httpServletResponse.getWriter()).thenReturn(pw); EmployeeServlet employeeServlet = new EmployeeServlet(); - employeeServlet.doPost(httpServletRequest, httpServletResponse); + employeeServlet.doGet(httpServletRequest, httpServletResponse); String employeeJsonString = sw.getBuffer().toString().trim(); Employee fetchedEmployee = new Gson().fromJson(employeeJsonString, Employee.class); diff --git a/jaxb/pom.xml b/jaxb/pom.xml index 26d7c8d362..f8e5ec0977 100644 --- a/jaxb/pom.xml +++ b/jaxb/pom.xml @@ -39,6 +39,11 @@ commons-lang3 ${commons-lang3.version} + + javax.activation + activation + 1.1 + diff --git a/jaxb/src/main/resources/log4jstructuraldp.properties b/jaxb/src/main/resources/log4jstructuraldp.properties new file mode 100644 index 0000000000..5bc2bfe4b9 --- /dev/null +++ b/jaxb/src/main/resources/log4jstructuraldp.properties @@ -0,0 +1,9 @@ + +# Root logger +log4j.rootLogger=INFO, file, stdout + +# Write to console +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java b/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java index b2dde85c0f..77b7f1a0b3 100644 --- a/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java +++ b/jaxb/src/test/java/com/baeldung/jaxb/test/JaxbIntegrationTest.java @@ -44,7 +44,7 @@ public class JaxbIntegrationTest { File bookFile = new File(this.getClass().getResource("/book.xml").getFile()); String sampleBookXML = FileUtils.readFileToString(sampleBookFile, "UTF-8"); String marshallerBookXML = FileUtils.readFileToString(bookFile, "UTF-8"); - Assert.assertEquals(sampleBookXML, marshallerBookXML); + Assert.assertEquals(sampleBookXML.replace("\r", "").replace("\n", ""), marshallerBookXML.replace("\r", "").replace("\n", "")); } @Test diff --git a/jaxb/src/test/resources/book.xml b/jaxb/src/test/resources/book.xml new file mode 100644 index 0000000000..605d531b16 --- /dev/null +++ b/jaxb/src/test/resources/book.xml @@ -0,0 +1,5 @@ + + + Book1 + 2016-12-16T17:28:49.718Z + diff --git a/jee-7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java b/jee-7/src/test/java/com/baeldung/convListVal/ConvListValLiveTest.java similarity index 98% rename from jee-7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/convListVal/ConvListValLiveTest.java index caeba95e45..0d6fd295e6 100644 --- a/jee-7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java +++ b/jee-7/src/test/java/com/baeldung/convListVal/ConvListValLiveTest.java @@ -22,7 +22,7 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @RunWith(Arquillian.class) -public class ConvListValIntegrationTest { +public class ConvListValLiveTest { @ArquillianResource private URL deploymentUrl; diff --git a/jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanLiveTest.java similarity index 98% rename from jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanLiveTest.java index 0e4c91ad67..41dde6549d 100644 --- a/jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanIntegrationTest.java +++ b/jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanLiveTest.java @@ -21,7 +21,7 @@ import static org.hamcrest.Matchers.equalTo; @RunWith(Arquillian.class) -public class AutomaticTimerBeanIntegrationTest { +public class AutomaticTimerBeanLiveTest { //the @AutomaticTimerBean has a method called every 10 seconds //testing the difference ==> 100000 diff --git a/jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanLiveTest.java similarity index 96% rename from jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanLiveTest.java index 13cd1729db..350c094f38 100644 --- a/jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanIntegrationTest.java +++ b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanLiveTest.java @@ -21,7 +21,7 @@ import static org.hamcrest.Matchers.is; @RunWith(Arquillian.class) -public class ProgrammaticAtFixedRateTimerBeanIntegrationTest { +public class ProgrammaticAtFixedRateTimerBeanLiveTest { final static long TIMEOUT = 1000; final static long TOLERANCE = 500l; diff --git a/jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanLiveTest.java similarity index 97% rename from jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanLiveTest.java index b90cb6d909..ad079c131b 100644 --- a/jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanIntegrationTest.java +++ b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanLiveTest.java @@ -19,7 +19,7 @@ import static org.hamcrest.Matchers.is; @RunWith(Arquillian.class) -public class ProgrammaticTimerBeanIntegrationTest { +public class ProgrammaticTimerBeanLiveTest { final static long TIMEOUT = 5000l; final static long TOLERANCE = 1000l; diff --git a/jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanLiveTest.java similarity index 96% rename from jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanLiveTest.java index e2e660f79b..974f0a285f 100644 --- a/jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanIntegrationTest.java +++ b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanLiveTest.java @@ -21,7 +21,7 @@ import static org.hamcrest.Matchers.is; @RunWith(Arquillian.class) -public class ProgrammaticWithFixedDelayTimerBeanIntegrationTest { +public class ProgrammaticWithFixedDelayTimerBeanLiveTest { final static long TIMEOUT = 15000l; final static long TOLERANCE = 1000l; diff --git a/jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanLiveTest.java similarity index 97% rename from jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanLiveTest.java index 580edade77..a4ed9ceb68 100644 --- a/jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanIntegrationTest.java +++ b/jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanLiveTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @RunWith(Arquillian.class) -public class ScheduleTimerBeanIntegrationTest { +public class ScheduleTimerBeanLiveTest { private final static long TIMEOUT = 5000l; private final static long TOLERANCE = 1000l; diff --git a/jhipster/jhipster-microservice/car-app/pom.xml b/jhipster/jhipster-microservice/car-app/pom.xml index 77e214234e..e5593bdbb9 100644 --- a/jhipster/jhipster-microservice/car-app/pom.xml +++ b/jhipster/jhipster-microservice/car-app/pom.xml @@ -3,10 +3,10 @@ 4.0.0 - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 com.car.app diff --git a/jhipster/jhipster-microservice/dealer-app/pom.xml b/jhipster/jhipster-microservice/dealer-app/pom.xml index beada8f064..3c21e0042f 100644 --- a/jhipster/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster/jhipster-microservice/dealer-app/pom.xml @@ -3,10 +3,10 @@ 4.0.0 - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 com.dealer.app diff --git a/jhipster/jhipster-microservice/gateway-app/pom.xml b/jhipster/jhipster-microservice/gateway-app/pom.xml index d90addf51b..42808e26ce 100644 --- a/jhipster/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster/jhipster-microservice/gateway-app/pom.xml @@ -3,10 +3,10 @@ 4.0.0 - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 com.gateway diff --git a/jhipster/jhipster-monolithic/pom.xml b/jhipster/jhipster-monolithic/pom.xml index fc8e8353b4..c8c9578fd6 100644 --- a/jhipster/jhipster-monolithic/pom.xml +++ b/jhipster/jhipster-monolithic/pom.xml @@ -3,10 +3,10 @@ 4.0.0 - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 com.baeldung diff --git a/jjwt/pom.xml b/jjwt/pom.xml index 51d4dcf1c0..2aa52b8818 100644 --- a/jjwt/pom.xml +++ b/jjwt/pom.xml @@ -10,10 +10,10 @@ Exercising the JJWT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/jmeter/pom.xml b/jmeter/pom.xml index bb5769ef57..5f9509f0be 100644 --- a/jmeter/pom.xml +++ b/jmeter/pom.xml @@ -9,10 +9,10 @@ Intro to Performance testing using JMeter - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureIntegrationTest.java b/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java similarity index 98% rename from jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureIntegrationTest.java rename to jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java index c0fb5485aa..8bc8c854da 100644 --- a/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureIntegrationTest.java +++ b/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java @@ -15,7 +15,7 @@ import org.junit.Test; import com.baeldung.jpa.model.Car; -public class StoredProcedureIntegrationTest { +public class StoredProcedureLiveTest { private static EntityManagerFactory factory = null; private static EntityManager entityManager = null; diff --git a/kotlin-js/README.md b/kotlin-js/README.md new file mode 100644 index 0000000000..445ad6da9a --- /dev/null +++ b/kotlin-js/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Kotlin and Javascript](http://www.baeldung.com/kotlin-javascript) diff --git a/libraries-data/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java index 61c98d0126..fd1e9c29a9 100644 --- a/libraries-data/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java +++ b/libraries-data/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java @@ -15,12 +15,13 @@ import static org.junit.Assert.assertEquals; public class EntryProcessorIntegrationTest { private static final String CACHE_NAME = "MyCache"; + private static final String CACHE_PROVIDER_NAME = "com.hazelcast.cache.HazelcastCachingProvider"; private Cache cache; @Before public void instantiateCache() { - CachingProvider cachingProvider = Caching.getCachingProvider(); + CachingProvider cachingProvider = Caching.getCachingProvider(CACHE_PROVIDER_NAME); CacheManager cacheManager = cachingProvider.getCacheManager(); MutableConfiguration config = new MutableConfiguration<>(); this.cache = cacheManager.createCache(CACHE_NAME, config); @@ -29,7 +30,7 @@ public class EntryProcessorIntegrationTest { @After public void tearDown() { - Caching.getCachingProvider().getCacheManager().destroyCache(CACHE_NAME); + Caching.getCachingProvider(CACHE_PROVIDER_NAME).getCacheManager().destroyCache(CACHE_NAME); } @Test diff --git a/libraries-data/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java index fcbfbe6111..512a75ec61 100644 --- a/libraries-data/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java +++ b/libraries-data/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java @@ -17,6 +17,7 @@ import static org.junit.Assert.assertEquals; public class EventListenerIntegrationTest { private static final String CACHE_NAME = "MyCache"; + private static final String CACHE_PROVIDER_NAME = "com.hazelcast.cache.HazelcastCachingProvider"; private Cache cache; private SimpleCacheEntryListener listener; @@ -24,7 +25,7 @@ public class EventListenerIntegrationTest { @Before public void setup() { - CachingProvider cachingProvider = Caching.getCachingProvider(); + CachingProvider cachingProvider = Caching.getCachingProvider(CACHE_PROVIDER_NAME); CacheManager cacheManager = cachingProvider.getCacheManager(); MutableConfiguration config = new MutableConfiguration(); this.cache = cacheManager.createCache("MyCache", config); @@ -33,7 +34,7 @@ public class EventListenerIntegrationTest { @After public void tearDown() { - Caching.getCachingProvider().getCacheManager().destroyCache(CACHE_NAME); + Caching.getCachingProvider(CACHE_PROVIDER_NAME).getCacheManager().destroyCache(CACHE_NAME); } @Test diff --git a/libraries-data/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java index fac3d32bcb..33521469fa 100644 --- a/libraries-data/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java +++ b/libraries-data/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java @@ -14,7 +14,7 @@ public class JCacheIntegrationTest { @Test public void instantiateCache() { - CachingProvider cachingProvider = Caching.getCachingProvider(); + CachingProvider cachingProvider = Caching.getCachingProvider("com.hazelcast.cache.HazelcastCachingProvider"); CacheManager cacheManager = cachingProvider.getCacheManager(); MutableConfiguration config = new MutableConfiguration<>(); Cache cache = cacheManager.createCache("simpleCache", config); diff --git a/libraries-data/src/test/resources/reladomo/ReladomoTestConfig.xml b/libraries-data/src/test/resources/reladomo/ReladomoTestConfig.xml index a1951f09b7..6e5d212fb8 100644 --- a/libraries-data/src/test/resources/reladomo/ReladomoTestConfig.xml +++ b/libraries-data/src/test/resources/reladomo/ReladomoTestConfig.xml @@ -2,6 +2,6 @@ - + \ No newline at end of file diff --git a/libraries/pom.xml b/libraries/pom.xml index 4f90d63d93..663b9e68bb 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -709,6 +709,20 @@ xchart ${xchart-version} + + + commons-net + commons-net + ${commons-net.version} + + + org.mockftpserver + MockFtpServer + ${mockftpserver.version} + test + + + @@ -923,6 +937,8 @@ 2.5.11 3.6.1 3.5.2 + 3.6 + 2.7.1 \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/commons/math3/Histogram.java b/libraries/src/main/java/com/baeldung/commons/math3/Histogram.java index 5b4097b1e4..a8c15887be 100644 --- a/libraries/src/main/java/com/baeldung/commons/math3/Histogram.java +++ b/libraries/src/main/java/com/baeldung/commons/math3/Histogram.java @@ -47,27 +47,29 @@ public class Histogram { private Map processRawData() { - List datasetList = Arrays.asList(36, 25, 38, 46, 55, 68, 72, 55, 36, 38, 67, 45, 22, 48, 91, 46, 52, 61, 58, 55); + List datasetList = Arrays.asList( + 36, 25, 38, 46, 55, 68, 72, + 55, 36, 38, 67, 45, 22, 48, + 91, 46, 52, 61, 58, 55); Frequency frequency = new Frequency(); datasetList.forEach(d -> frequency.addValue(Double.parseDouble(d.toString()))); - List processed = new ArrayList(); - datasetList.forEach(d -> { - double observation = Double.parseDouble(d.toString()); + datasetList.stream() + .map(d -> Double.parseDouble(d.toString())) + .distinct() + .forEach(observation -> { + long observationFrequency = frequency.getCount(observation); + int upperBoundary = (observation > classWidth) + ? Math.multiplyExact( (int) Math.ceil(observation / classWidth), classWidth) + : classWidth; + int lowerBoundary = (upperBoundary > classWidth) + ? Math.subtractExact(upperBoundary, classWidth) + : 0; + String bin = lowerBoundary + "-" + upperBoundary; - if(processed.contains(observation)) - return; + updateDistributionMap(lowerBoundary, bin, observationFrequency); - long observationFrequency = frequency.getCount(observation); - int upperBoundary = (observation > classWidth) ? Math.multiplyExact( (int) Math.ceil(observation / classWidth), classWidth) : classWidth; - int lowerBoundary = (upperBoundary > classWidth) ? Math.subtractExact(upperBoundary, classWidth) : 0; - String bin = lowerBoundary + "-" + upperBoundary; - - updateDistributionMap(lowerBoundary, bin, observationFrequency); - - processed.add(observation); - - }); + }); return distributionMap; } diff --git a/libraries/src/main/java/com/baeldung/ftp/FtpClient.java b/libraries/src/main/java/com/baeldung/ftp/FtpClient.java new file mode 100644 index 0000000000..209bed35f0 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/ftp/FtpClient.java @@ -0,0 +1,63 @@ +package com.baeldung.ftp; + +import org.apache.commons.net.PrintCommandListener; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; +import org.apache.commons.net.ftp.FTPReply; + +import java.io.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +class FtpClient { + + private final String server; + private final int port; + private final String user; + private final String password; + private FTPClient ftp; + + FtpClient(String server, int port, String user, String password) { + this.server = server; + this.port = port; + this.user = user; + this.password = password; + } + + void open() throws IOException { + ftp = new FTPClient(); + + ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); + + ftp.connect(server, port); + int reply = ftp.getReplyCode(); + if (!FTPReply.isPositiveCompletion(reply)) { + ftp.disconnect(); + throw new IOException("Exception in connecting to FTP Server"); + } + + ftp.login(user, password); + } + + void close() throws IOException { + ftp.disconnect(); + } + + Collection listFiles(String path) throws IOException { + FTPFile[] files = ftp.listFiles(path); + + return Arrays.stream(files) + .map(FTPFile::getName) + .collect(Collectors.toList()); + } + + void putFileToPath(File file, String path) throws IOException { + ftp.storeFile(path, new FileInputStream(file)); + } + + void downloadFile(String source, String destination) throws IOException { + FileOutputStream out = new FileOutputStream(destination); + ftp.retrieveFile(source, out); + } +} diff --git a/libraries/src/main/java/com/baeldung/javalin/User/UserController.java b/libraries/src/main/java/com/baeldung/javalin/User/UserController.java index fd713606cf..685890c6d7 100644 --- a/libraries/src/main/java/com/baeldung/javalin/User/UserController.java +++ b/libraries/src/main/java/com/baeldung/javalin/User/UserController.java @@ -14,7 +14,7 @@ public class UserController { public static Handler fetchById = ctx -> { int id = Integer.parseInt(Objects.requireNonNull(ctx.param("id"))); UserDao dao = UserDao.instance(); - User user = dao.getUserById(id); + User user = dao.getUserById(id).get(); if (user == null) { ctx.html("Not Found"); } else { diff --git a/libraries/src/test/java/com/baeldung/ftp/FtpClientIntegrationTest.java b/libraries/src/test/java/com/baeldung/ftp/FtpClientIntegrationTest.java new file mode 100644 index 0000000000..43da69f96d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/ftp/FtpClientIntegrationTest.java @@ -0,0 +1,73 @@ +package com.baeldung.ftp; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockftpserver.fake.FakeFtpServer; +import org.mockftpserver.fake.UserAccount; +import org.mockftpserver.fake.filesystem.DirectoryEntry; +import org.mockftpserver.fake.filesystem.FileEntry; +import org.mockftpserver.fake.filesystem.FileSystem; +import org.mockftpserver.fake.filesystem.UnixFakeFileSystem; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Collection; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FtpClientIntegrationTest { + + private FakeFtpServer fakeFtpServer; + + private FtpClient ftpClient; + + @Before + public void setup() throws IOException { + fakeFtpServer = new FakeFtpServer(); + fakeFtpServer.addUserAccount(new UserAccount("user", "password", "/data")); + + FileSystem fileSystem = new UnixFakeFileSystem(); + fileSystem.add(new DirectoryEntry("/data")); + fileSystem.add(new FileEntry("/data/foobar.txt", "abcdef 1234567890")); + fakeFtpServer.setFileSystem(fileSystem); + fakeFtpServer.setServerControlPort(0); + + fakeFtpServer.start(); + + ftpClient = new FtpClient("localhost", fakeFtpServer.getServerControlPort(), "user", "password"); + ftpClient.open(); + } + + @After + public void teardown() throws IOException { + ftpClient.close(); + fakeFtpServer.stop(); + } + + @Test + public void givenRemoteFile_whenListingRemoteFiles_thenItIsContainedInList() throws IOException { + Collection files = ftpClient.listFiles(""); + + assertThat(files).contains("foobar.txt"); + } + + @Test + public void givenRemoteFile_whenDownloading_thenItIsOnTheLocalFilesystem() throws IOException { + ftpClient.downloadFile("/foobar.txt", "downloaded_buz.txt"); + + assertThat(new File("downloaded_buz.txt")).exists(); + new File("downloaded_buz.txt").delete(); // cleanup + } + + @Test + public void givenLocalFile_whenUploadingIt_thenItExistsOnRemoteLocation() throws URISyntaxException, IOException { + File file = new File(getClass().getClassLoader().getResource("ftp/baz.txt").toURI()); + + ftpClient.putFileToPath(file, "/buz.txt"); + + assertThat(fakeFtpServer.getFileSystem().exists("/buz.txt")).isTrue(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/ftp/JdkFtpClientIntegrationTest.java b/libraries/src/test/java/com/baeldung/ftp/JdkFtpClientIntegrationTest.java new file mode 100644 index 0000000000..ef6809b02d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/ftp/JdkFtpClientIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.ftp; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockftpserver.fake.FakeFtpServer; +import org.mockftpserver.fake.UserAccount; +import org.mockftpserver.fake.filesystem.DirectoryEntry; +import org.mockftpserver.fake.filesystem.FileEntry; +import org.mockftpserver.fake.filesystem.FileSystem; +import org.mockftpserver.fake.filesystem.UnixFakeFileSystem; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.util.Collection; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JdkFtpClientIntegrationTest { + + private FakeFtpServer fakeFtpServer; + + + @Before + public void setup() throws IOException { + fakeFtpServer = new FakeFtpServer(); + fakeFtpServer.addUserAccount(new UserAccount("user", "password", "/data")); + + FileSystem fileSystem = new UnixFakeFileSystem(); + fileSystem.add(new DirectoryEntry("/data")); + fileSystem.add(new FileEntry("/data/foobar.txt", "abcdef 1234567890")); + fakeFtpServer.setFileSystem(fileSystem); + fakeFtpServer.setServerControlPort(0); + + fakeFtpServer.start(); + } + + @After + public void teardown() throws IOException { + fakeFtpServer.stop(); + } + + @Test + public void givenRemoteFile_whenDownloading_thenItIsOnTheLocalFilesystem() throws IOException { + String ftpUrl = String.format("ftp://user:password@localhost:%d/foobar.txt", fakeFtpServer.getServerControlPort()); + + URLConnection urlConnection = new URL(ftpUrl).openConnection(); + InputStream inputStream = urlConnection.getInputStream(); + Files.copy(inputStream, new File("downloaded_buz.txt").toPath()); + inputStream.close(); + + assertThat(new File("downloaded_buz.txt")).exists(); + + new File("downloaded_buz.txt").delete(); // cleanup + } + +} diff --git a/libraries/src/test/resources/ftp/baz.txt b/libraries/src/test/resources/ftp/baz.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java index e4404a6528..53634002a0 100644 --- a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java @@ -12,6 +12,7 @@ import org.apache.logging.log4j.Logger; import org.junit.Before; import org.junit.Test; + import com.fasterxml.jackson.databind.ObjectMapper; public class JSONLayoutIntegrationTest extends Log4j2BaseIntegrationTest { diff --git a/mesos-marathon/pom.xml b/mesos-marathon/pom.xml index 2b7a238ee8..77d13cd5c6 100644 --- a/mesos-marathon/pom.xml +++ b/mesos-marathon/pom.xml @@ -7,10 +7,10 @@ 0.0.1-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/msf4j/README.md b/msf4j/README.md new file mode 100644 index 0000000000..7c66b8dc5f --- /dev/null +++ b/msf4j/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Introduction to Java Microservices with MSF4J](http://www.baeldung.com/msf4j) diff --git a/msf4j/pom.xml b/msf4j/pom.xml new file mode 100644 index 0000000000..f691d746b7 --- /dev/null +++ b/msf4j/pom.xml @@ -0,0 +1,32 @@ + + + + org.wso2.msf4j + msf4j-service + 2.6.0 + + 4.0.0 + + com.baeldung.msf4j + msf4j + 0.0.1-SNAPSHOT + WSO2 MSF4J Microservice + + + com.baeldung.msf4j.msf4jintro.Application + + + + org.wso2.msf4j + msf4j-spring + 2.6.1 + + + org.wso2.msf4j + msf4j-mustache-template + 2.6.1 + + + + \ No newline at end of file diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/Application.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/Application.java new file mode 100644 index 0000000000..c4cf136536 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/Application.java @@ -0,0 +1,11 @@ +package com.baeldung.msf4j.msf4japi; + +import org.wso2.msf4j.MicroservicesRunner; + +public class Application { + public static void main(String[] args) { + new MicroservicesRunner() + .deploy(new MenuService()) + .start(); + } +} \ No newline at end of file diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/Meal.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/Meal.java new file mode 100644 index 0000000000..d17a7a1034 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/Meal.java @@ -0,0 +1,20 @@ +package com.baeldung.msf4j.msf4japi; + +public class Meal { + private String name; + private Float price; + + public Meal(String name, Float price) { + this.name = name; + this.price = price; + } + + public String getName() { + return name; + } + + public Float getPrice() { + return price; + } + +} diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/MenuService.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/MenuService.java new file mode 100644 index 0000000000..4f880a1393 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4japi/MenuService.java @@ -0,0 +1,78 @@ +package com.baeldung.msf4j.msf4japi; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +import com.google.gson.Gson; + +@Path("/menu") +public class MenuService { + + private List meals = new ArrayList(); + + public MenuService() { + meals.add(new Meal("Java beans",42.0f)); + } + + @GET + @Path("/") + @Produces({ "application/json" }) + public Response index() { + return Response.ok() + .entity(meals) + .build(); + } + + @GET + @Path("/{id}") + @Produces({ "application/json" }) + public Response meal(@PathParam("id") int id) { + return Response.ok() + .entity(meals.get(id)) + .build(); + } + + + @POST + @Path("/") + @Consumes("application/json") + @Produces({ "application/json" }) + public Response create(Meal meal) { + meals.add(meal); + return Response.ok() + .entity(meal) + .build(); + } + + @PUT + @Path("/{id}") + @Consumes("application/json") + @Produces({ "application/json" }) + public Response update(@PathParam("id") int id, Meal meal) { + meals.set(id, meal); + return Response.ok() + .entity(meal) + .build(); + } + + @DELETE + @Path("/{id}") + @Produces({ "application/json" }) + public Response delete(@PathParam("id") int id) { + Meal meal = meals.get(id); + meals.remove(id); + return Response.ok() + .entity(meal) + .build(); + } +} diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jintro/Application.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jintro/Application.java new file mode 100644 index 0000000000..dc4a060056 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jintro/Application.java @@ -0,0 +1,11 @@ +package com.baeldung.msf4j.msf4jintro; + +import org.wso2.msf4j.MicroservicesRunner; + +public class Application { + public static void main(String[] args) { + new MicroservicesRunner() + .deploy(new SimpleService()) + .start(); + } +} \ No newline at end of file diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jintro/SimpleService.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jintro/SimpleService.java new file mode 100644 index 0000000000..bcb52859b5 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jintro/SimpleService.java @@ -0,0 +1,21 @@ +package com.baeldung.msf4j.msf4jintro; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +@Path("/") +public class SimpleService { + + @GET + public String index() { + return "Default content"; + } + + @GET + @Path("/say/{name}") + public String say(@PathParam("name") String name) { + return "Hello " + name; + } + +} diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/Application.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/Application.java new file mode 100644 index 0000000000..2a5232a7e6 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/Application.java @@ -0,0 +1,10 @@ +package com.baeldung.msf4j.msf4jspring; + +import org.wso2.msf4j.spring.MSF4JSpringApplication; + +public class Application { + + public static void main(String[] args) { + MSF4JSpringApplication.run(Application.class, args); + } +} \ No newline at end of file diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/configuration/PortConfiguration.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/configuration/PortConfiguration.java new file mode 100644 index 0000000000..c3313fc3b1 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/configuration/PortConfiguration.java @@ -0,0 +1,15 @@ +package com.baeldung.msf4j.msf4jspring.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.wso2.msf4j.spring.transport.HTTPTransportConfig; + +@Configuration +public class PortConfiguration { + + @Bean + public HTTPTransportConfig http() { + return new HTTPTransportConfig(9090); + } + +} \ No newline at end of file diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/domain/Meal.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/domain/Meal.java new file mode 100644 index 0000000000..99de0abc4c --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/domain/Meal.java @@ -0,0 +1,20 @@ +package com.baeldung.msf4j.msf4jspring.domain; + +public class Meal { + private String name; + private Float price; + + public Meal(String name, Float price) { + this.name = name; + this.price = price; + } + + public String getName() { + return name; + } + + public Float getPrice() { + return price; + } + +} diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/repositories/MealRepository.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/repositories/MealRepository.java new file mode 100644 index 0000000000..4d9e54348e --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/repositories/MealRepository.java @@ -0,0 +1,37 @@ +package com.baeldung.msf4j.msf4jspring.repositories; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Component; +import com.baeldung.msf4j.msf4jspring.domain.Meal; + +@Component +public class MealRepository { + + private List meals = new ArrayList(); + + public MealRepository() { + meals.add(new Meal("Salad", 4.2f)); + meals.add(new Meal("Litre of cola", 2.99f)); + } + + public void create(Meal meal) { + meals.add(meal); + } + + public void remove(Meal meal) { + meals.remove(meal); + } + + public Meal find(int id) { + return meals.get(id); + } + + public List findAll() { + return meals; + } + + public void update(int id, Meal meal) { + meals.set(id, meal); + } +} \ No newline at end of file diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/resources/MealResource.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/resources/MealResource.java new file mode 100644 index 0000000000..9c617257cb --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/resources/MealResource.java @@ -0,0 +1,47 @@ +package com.baeldung.msf4j.msf4jspring.resources; + +import java.util.Collections; +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.wso2.msf4j.template.MustacheTemplateEngine; + +import com.baeldung.msf4j.msf4jspring.services.MealService; + +@Component +@Path("/meal") +public class MealResource { + + @Autowired + private MealService mealService; + + @GET + @Path("/") + public Response all() { + Map map = Collections.singletonMap("meals", mealService.findAll()); + String html = MustacheTemplateEngine.instance() + .render("meals.mustache", map); + return Response.ok() + .type(MediaType.TEXT_HTML) + .entity(html) + .build(); + } + + @GET + @Path("/{id}") + @Produces({ "text/xml" }) + public Response meal(@PathParam("id") int id) { + return Response.ok() + .entity(mealService.find(id)) + .build(); + } + +} diff --git a/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/services/MealService.java b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/services/MealService.java new file mode 100644 index 0000000000..fd6a519999 --- /dev/null +++ b/msf4j/src/main/java/com/baeldung/msf4j/msf4jspring/services/MealService.java @@ -0,0 +1,27 @@ +package com.baeldung.msf4j.msf4jspring.services; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.msf4j.msf4jspring.domain.Meal; +import com.baeldung.msf4j.msf4jspring.repositories.MealRepository; + +@Service +public class MealService { + @Autowired + private MealRepository mealRepository; + + public Meal find(int id) { + return mealRepository.find(id); + } + + public List findAll() { + return mealRepository.findAll(); + } + + public void create(Meal meal) { + mealRepository.create(meal); + } +} diff --git a/msf4j/src/main/resources/application.properties b/msf4j/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/msf4j/src/main/resources/templates/meals.mustache b/msf4j/src/main/resources/templates/meals.mustache new file mode 100644 index 0000000000..f4bdfaccf9 --- /dev/null +++ b/msf4j/src/main/resources/templates/meals.mustache @@ -0,0 +1,13 @@ + + + Meals + + +
+

Today's Meals

+ {{#meals}} +
{{name}}: {{price}}$
+ {{/meals}} +
+ + \ No newline at end of file diff --git a/mvn-wrapper/pom.xml b/mvn-wrapper/pom.xml index 6fb9bfeffc..e26df81139 100644 --- a/mvn-wrapper/pom.xml +++ b/mvn-wrapper/pom.xml @@ -9,10 +9,10 @@ Setting up the Maven Wrapper - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/parent-boot-5/README.md b/parent-boot-1/README.md similarity index 100% rename from parent-boot-5/README.md rename to parent-boot-1/README.md diff --git a/parent-boot-5/pom.xml b/parent-boot-1/pom.xml similarity index 96% rename from parent-boot-5/pom.xml rename to parent-boot-1/pom.xml index 32bb2eab04..af14d88aff 100644 --- a/parent-boot-5/pom.xml +++ b/parent-boot-1/pom.xml @@ -2,16 +2,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung - parent-boot-5 + parent-boot-1 0.0.1-SNAPSHOT pom - Parent Boot 5 - Parent for all spring boot 1.5 modules + Parent for all Spring Boot 1.x modules org.springframework.boot spring-boot-starter-parent - 1.5.10.RELEASE + 1.5.13.RELEASE diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index a9c54dece9..625a96ff9d 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -105,6 +105,25 @@ + + thin-jar + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.springframework.boot.experimental + spring-boot-thin-layout + ${thin.version} + + + + + + @@ -115,6 +134,7 @@ 1.8 1.8 + 1.0.11.RELEASE \ No newline at end of file diff --git a/patterns/design-patterns/README.md b/patterns/design-patterns/README.md index fb80f4bd6a..77ead0b317 100644 --- a/patterns/design-patterns/README.md +++ b/patterns/design-patterns/README.md @@ -8,4 +8,4 @@ - [Service Locator Pattern](http://www.baeldung.com/java-service-locator-pattern) - [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking) - [Composite Design Pattern in Java](http://www.baeldung.com/java-composite-pattern) - +- [Visitor Design Pattern in Java](http://www.baeldung.com/java-visitor-pattern) diff --git a/patterns/design-patterns/src/main/resources/log4jstructuraldp.properties b/patterns/design-patterns/src/main/resources/log4jstructuraldp.properties new file mode 100644 index 0000000000..5bc2bfe4b9 --- /dev/null +++ b/patterns/design-patterns/src/main/resources/log4jstructuraldp.properties @@ -0,0 +1,9 @@ + +# Root logger +log4j.rootLogger=INFO, file, stdout + +# Write to console +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/performance-tests/README.md b/performance-tests/README.md new file mode 100644 index 0000000000..5af735b708 --- /dev/null +++ b/performance-tests/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Performance of Java Mapping Frameworks](http://www.baeldung.com/java-performance-mapping-frameworks) diff --git a/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java b/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java index 9a45f032a6..fe770aef24 100644 --- a/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java +++ b/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java @@ -4,13 +4,32 @@ import com.baeldung.performancetests.dozer.DozerConverter; import com.baeldung.performancetests.jmapper.JMapperConverter; import com.baeldung.performancetests.mapstruct.MapStructConverter; import com.baeldung.performancetests.model.destination.DestinationCode; -import com.baeldung.performancetests.model.source.*; import com.baeldung.performancetests.model.destination.Order; +import com.baeldung.performancetests.model.source.AccountStatus; +import com.baeldung.performancetests.model.source.Address; +import com.baeldung.performancetests.model.source.DeliveryData; +import com.baeldung.performancetests.model.source.Discount; +import com.baeldung.performancetests.model.source.OrderStatus; +import com.baeldung.performancetests.model.source.PaymentType; +import com.baeldung.performancetests.model.source.Product; +import com.baeldung.performancetests.model.source.RefundPolicy; +import com.baeldung.performancetests.model.source.Review; +import com.baeldung.performancetests.model.source.Shop; +import com.baeldung.performancetests.model.source.SourceCode; +import com.baeldung.performancetests.model.source.SourceOrder; +import com.baeldung.performancetests.model.source.User; import com.baeldung.performancetests.modelmapper.ModelMapperConverter; import com.baeldung.performancetests.orika.OrikaConverter; -import org.junit.Assert; -import org.junit.Test; -import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Group; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.runner.RunnerException; import java.io.IOException; @@ -21,14 +40,24 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; +@Fork(value = 1, warmups = 5) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@BenchmarkMode(Mode.All) +@Measurement(iterations = 5) @State(Scope.Group) public class MappingFrameworksPerformance { - SourceOrder sourceOrder = null; - SourceCode sourceCode = null; + private SourceOrder sourceOrder = null; + private SourceCode sourceCode = null; + private static final OrikaConverter ORIKA_CONVERTER = new OrikaConverter(); + private static final JMapperConverter JMAPPER_CONVERTER = new JMapperConverter(); + private static final ModelMapperConverter MODEL_MAPPER_CONVERTER = new ModelMapperConverter(); + private static final DozerConverter DOZER_CONVERTER = new DozerConverter(); + @Setup public void setUp() { User user = new User("John", "John@doe.com", AccountStatus.ACTIVE); - RefundPolicy refundPolicy = new RefundPolicy(true, 30, Collections.singletonList("Refundable only if not used!")); + RefundPolicy refundPolicy = new RefundPolicy(true, 30, Collections + .singletonList("Refundable only if not used!")); Product product = new Product(BigDecimal.valueOf(10.99), 100, @@ -51,7 +80,7 @@ public class MappingFrameworksPerformance { List reviewList = new ArrayList<>(); reviewList.add(review); reviewList.add(negativeReview); - Shop shop = new Shop("Super Shop", shopAddress,"www.super-shop.com",reviewList); + Shop shop = new Shop("Super Shop", shopAddress, "www.super-shop.com", reviewList); sourceOrder = new SourceOrder(OrderStatus.CONFIRMED, Instant.now().toString(), @@ -68,126 +97,67 @@ public class MappingFrameworksPerformance { sourceCode = new SourceCode("This is source code!"); } - public void main(String[] args) throws IOException, RunnerException { org.openjdk.jmh.Main.main(args); } - @Benchmark @Group("realLifeTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void orikaMapperRealLifeBenchmark() { - OrikaConverter orikaConverter = new OrikaConverter(); - Order mappedOrder = orikaConverter.convert(sourceOrder); - Assert.assertEquals(mappedOrder, sourceOrder); - + public Order orikaMapperRealLifeBenchmark() { + return ORIKA_CONVERTER.convert(sourceOrder); } @Benchmark @Group("realLifeTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void jmapperRealLifeBenchmark() { - JMapperConverter jmapperConverter = new JMapperConverter(); - Order mappedOrder = jmapperConverter.convert(sourceOrder); - Assert.assertEquals(mappedOrder, sourceOrder); + public Order jmapperRealLifeBenchmark() { + return JMAPPER_CONVERTER.convert(sourceOrder); } @Benchmark @Group("realLifeTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void modelMapperRealLifeBenchmark() { - ModelMapperConverter modelMapperConverter = new ModelMapperConverter(); - Order mappedOrder = modelMapperConverter.convert(sourceOrder); - Assert.assertEquals(mappedOrder, sourceOrder); - } - - - @Benchmark - @Group("realLifeTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void dozerMapperRealLifeBenchmark() { - DozerConverter dozerConverter = new DozerConverter(); - Order mappedOrder = dozerConverter.convert(sourceOrder); - Assert.assertEquals(mappedOrder, sourceOrder); - + public Order modelMapperRealLifeBenchmark() { + return MODEL_MAPPER_CONVERTER.convert(sourceOrder); } @Benchmark @Group("realLifeTest") - @Fork(value = 1, warmups = 1) - @BenchmarkMode(Mode.All) - public void mapStructRealLifeMapperBenchmark() { - MapStructConverter converter = MapStructConverter.MAPPER; - Order mappedOrder = converter.convert(sourceOrder); - Assert.assertEquals(mappedOrder, sourceOrder); + public Order dozerMapperRealLifeBenchmark() { + return DOZER_CONVERTER.convert(sourceOrder); + } + + @Benchmark + @Group("realLifeTest") + public Order mapStructRealLifeMapperBenchmark() { + return MapStructConverter.MAPPER.convert(sourceOrder); } @Benchmark @Group("simpleTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void orikaMapperSimpleBenchmark() { - OrikaConverter orikaConverter = new OrikaConverter(); - DestinationCode mappedCode = orikaConverter.convert(sourceCode); - Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); - + public DestinationCode orikaMapperSimpleBenchmark() { + return ORIKA_CONVERTER.convert(sourceCode); } @Benchmark @Group("simpleTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void jmapperSimpleBenchmark() { - JMapperConverter jmapperConverter = new JMapperConverter(); - DestinationCode mappedCode = jmapperConverter.convert(sourceCode); - Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); + public DestinationCode jmapperSimpleBenchmark() { + return JMAPPER_CONVERTER.convert(sourceCode); } @Benchmark @Group("simpleTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void modelMapperBenchmark() { - ModelMapperConverter modelMapperConverter = new ModelMapperConverter(); - DestinationCode mappedCode = modelMapperConverter.convert(sourceCode); - Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); - } - - - @Benchmark - @Group("simpleTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void dozerMapperSimpleBenchmark() { - DozerConverter dozerConverter = new DozerConverter(); - Order mappedOrder = dozerConverter.convert(sourceOrder); - Assert.assertEquals(mappedOrder, sourceOrder); - + public DestinationCode modelMapperBenchmark() { + return MODEL_MAPPER_CONVERTER.convert(sourceCode); } @Benchmark @Group("simpleTest") - @Fork(value = 1, warmups = 1) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - @BenchmarkMode(Mode.All) - public void mapStructMapperSimpleBenchmark() { - MapStructConverter converter = MapStructConverter.MAPPER; - DestinationCode mappedCode = converter.convert(sourceCode); - Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); + public Order dozerMapperSimpleBenchmark() { + return DOZER_CONVERTER.convert(sourceOrder); } - + @Benchmark + @Group("simpleTest") + public DestinationCode mapStructMapperSimpleBenchmark() { + return MapStructConverter.MAPPER.convert(sourceCode); + } } diff --git a/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java index 1862d6b035..860ca0927a 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java @@ -27,7 +27,9 @@ public class RedissonConfigurationIntegrationTest { @AfterClass public static void destroy() { redisServer.stop(); - client.shutdown(); + if (client != null) { + client.shutdown(); + } } @Test diff --git a/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java index 766963e5cf..53d77c2699 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java @@ -37,7 +37,9 @@ public class RedissonIntegrationTest { @AfterClass public static void destroy() { redisServer.stop(); - client.shutdown(); + if (client != null) { + client.shutdown(); + } } @Test diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index b115c0e087..b1b7c8237b 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -9,10 +9,10 @@ This is simple boot application for Spring boot actuator test - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md index cb71d386e2..02d4306ecb 100644 --- a/persistence-modules/spring-jpa/README.md +++ b/persistence-modules/spring-jpa/README.md @@ -22,6 +22,7 @@ - [Obtaining Auto-generated Keys in Spring JDBC](http://www.baeldung.com/spring-jdbc-autogenerated-keys) - [Transactions with Spring 4 and JPA](http://www.baeldung.com/transaction-configuration-with-jpa-and-spring) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) +- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) ### Eclipse Config After importing the project into Eclipse, you may see the following error: diff --git a/pom.xml b/pom.xml index d60ee36b3d..31bf977b95 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ pom - parent-boot-5 + parent-boot-1 parent-boot-2 parent-spring-4 parent-spring-5 @@ -102,6 +102,7 @@ metrics maven mesos-marathon + msf4j testing-modules/mockito testing-modules/mockito-2 testing-modules/mocks @@ -261,8 +262,9 @@ java-spi performance-tests twilio - spring-boot-ctx-fluent + spring-boot-ctx-fluent java-ee-8-security-api + spring-webflux-amqp diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java index 477a2a1cb8..ec766ac7ac 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java @@ -18,26 +18,27 @@ public class AutomapInterfaceIntegrationTest { private ConnectionProvider connectionProvider = Connector.connectionProvider; private Database db = Database.from(connectionProvider); - private Observable create = null; + private Observable truncate = null; private Observable insert1, insert2 = null; @Before public void setup() { - create = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int primary key, name varchar(255))") + Observable create = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int primary key, name varchar(255))") .count(); + truncate = db.update("TRUNCATE TABLE EMPLOYEE") + .dependsOn(create) + .count(); insert1 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(1, 'Alan')") - .dependsOn(create) + .dependsOn(truncate) .count(); insert2 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(2, 'Sarah')") - .dependsOn(create) + .dependsOn(insert1) .count(); } @Test public void whenSelectFromTableAndAutomap_thenCorrect() { List employees = db.select("select id, name from EMPLOYEE") - .dependsOn(create) - .dependsOn(insert1) .dependsOn(insert2) .autoMap(Employee.class) .toList() @@ -57,7 +58,7 @@ public class AutomapInterfaceIntegrationTest { @After public void close() { db.update("DROP TABLE EMPLOYEE") - .dependsOn(create); + .dependsOn(truncate); connectionProvider.close(); } } diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java index 5f445234d7..2fb3b3abd7 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java @@ -22,24 +22,24 @@ public class BasicQueryTypesIntegrationTest { @Test public void whenCreateTableAndInsertRecords_thenCorrect() { - create = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int primary key, name varchar(255))") + create = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE_TABLE(id int primary key, name varchar(255))") .count(); - Observable insert1 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(1, 'John')") + Observable insert1 = db.update("INSERT INTO EMPLOYEE_TABLE(id, name) VALUES(1, 'John')") .dependsOn(create) .count(); - Observable update = db.update("UPDATE EMPLOYEE SET name = 'Alan' WHERE id = 1") + Observable update = db.update("UPDATE EMPLOYEE_TABLE SET name = 'Alan' WHERE id = 1") .dependsOn(create) .count(); - Observable insert2 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(2, 'Sarah')") + Observable insert2 = db.update("INSERT INTO EMPLOYEE_TABLE(id, name) VALUES(2, 'Sarah')") .dependsOn(create) .count(); - Observable insert3 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(3, 'Mike')") + Observable insert3 = db.update("INSERT INTO EMPLOYEE_TABLE(id, name) VALUES(3, 'Mike')") .dependsOn(create) .count(); - Observable delete = db.update("DELETE FROM EMPLOYEE WHERE id = 2") + Observable delete = db.update("DELETE FROM EMPLOYEE_TABLE WHERE id = 2") .dependsOn(create) .count(); - List names = db.select("select name from EMPLOYEE where id < ?") + List names = db.select("select name from EMPLOYEE_TABLE where id < ?") .parameter(3) .dependsOn(create) .dependsOn(insert1) @@ -57,7 +57,7 @@ public class BasicQueryTypesIntegrationTest { @After public void close() { - db.update("DROP TABLE EMPLOYEE") + db.update("DROP TABLE EMPLOYEE_TABLE") .dependsOn(create); connectionProvider.close(); } diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java index 189bca4adb..284ecc4078 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java @@ -27,7 +27,7 @@ public class InsertClobIntegrationTest { @Before public void setup() throws IOException { - create = db.update("CREATE TABLE IF NOT EXISTS SERVERLOG (id int primary key, document CLOB)") + create = db.update("CREATE TABLE IF NOT EXISTS SERVERLOG_TABLE (id int primary key, document CLOB)") .count(); InputStream actualInputStream = new FileInputStream("src/test/resources/actual_clob"); @@ -35,7 +35,7 @@ public class InsertClobIntegrationTest { InputStream expectedInputStream = new FileInputStream("src/test/resources/expected_clob"); this.expectedDocument = Utils.getStringFromInputStream(expectedInputStream); - this.insert = db.update("insert into SERVERLOG(id,document) values(?,?)") + this.insert = db.update("insert into SERVERLOG_TABLE(id,document) values(?,?)") .parameter(1) .parameter(Database.toSentinelIfNull(actualDocument)) .dependsOn(create) @@ -44,7 +44,7 @@ public class InsertClobIntegrationTest { @Test public void whenSelectCLOB_thenCorrect() throws IOException { - db.select("select document from SERVERLOG where id = 1") + db.select("select document from SERVERLOG_TABLE where id = 1") .dependsOn(create) .dependsOn(insert) .getAs(String.class) @@ -56,7 +56,7 @@ public class InsertClobIntegrationTest { @After public void close() { - db.update("DROP TABLE SERVERLOG") + db.update("DROP TABLE SERVERLOG_TABLE") .dependsOn(create); connectionProvider.close(); } diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java index 2018a9427c..c9e06a347f 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java @@ -22,14 +22,14 @@ public class ReturnKeysIntegrationTest { @Before public void setup() { begin = db.beginTransaction(); - createStatement = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int auto_increment primary key, name varchar(255))") + createStatement = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE_SAMPLE(id int auto_increment primary key, name varchar(255))") .dependsOn(begin) .count(); } @Test public void whenInsertAndReturnGeneratedKey_thenCorrect() { - Integer key = db.update("INSERT INTO EMPLOYEE(name) VALUES('John')") + Integer key = db.update("INSERT INTO EMPLOYEE_SAMPLE(name) VALUES('John')") .dependsOn(createStatement) .returnGeneratedKeys() .getAs(Integer.class) @@ -41,7 +41,7 @@ public class ReturnKeysIntegrationTest { @After public void close() { - db.update("DROP TABLE EMPLOYEE") + db.update("DROP TABLE EMPLOYEE_SAMPLE") .dependsOn(createStatement); connectionProvider.close(); } diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java index 4e24d7f10e..d5f09be23c 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java @@ -24,8 +24,11 @@ public class TransactionIntegrationTest { .update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int primary key, name varchar(255))") .dependsOn(begin) .count(); + Observable truncateStatement = db.update("TRUNCATE TABLE EMPLOYEE") + .dependsOn(createStatement) + .count(); Observable insertStatement = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(1, 'John')") - .dependsOn(createStatement) + .dependsOn(truncateStatement) .count(); Observable updateStatement = db.update("UPDATE EMPLOYEE SET name = 'Tom' WHERE id = 1") .dependsOn(insertStatement) diff --git a/spring-5-reactive/README.md b/spring-5-reactive/README.md index 9998dbf751..df96d933ba 100644 --- a/spring-5-reactive/README.md +++ b/spring-5-reactive/README.md @@ -17,3 +17,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Boot Actuator](http://www.baeldung.com/spring-boot-actuators) - [Spring Webflux Filters](http://www.baeldung.com/spring-webflux-filters) - [Reactive Flow with MongoDB, Kotlin, and Spring WebFlux](http://www.baeldung.com/kotlin-mongodb-spring-webflux) +- [Spring Data Reactive Repositories with MongoDB](http://www.baeldung.com/spring-data-mongodb-reactive) diff --git a/spring-all/pom.xml b/spring-all/pom.xml index f9ced963e7..c509622fca 100644 --- a/spring-all/pom.xml +++ b/spring-all/pom.xml @@ -8,10 +8,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-amqp-simple/pom.xml b/spring-amqp-simple/pom.xml index f3dfbccaec..eb0f25d1a7 100644 --- a/spring-amqp-simple/pom.xml +++ b/spring-amqp-simple/pom.xml @@ -8,10 +8,10 @@ Spring AMQP Simple App - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-aop/pom.xml b/spring-aop/pom.xml index 7cdf9bd7cc..0f4e08baa3 100644 --- a/spring-aop/pom.xml +++ b/spring-aop/pom.xml @@ -8,10 +8,10 @@ spring-aop - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-boot-bootstrap/pom.xml b/spring-boot-bootstrap/pom.xml index ecc72c85f5..ff5bca615b 100644 --- a/spring-boot-bootstrap/pom.xml +++ b/spring-boot-bootstrap/pom.xml @@ -88,6 +88,28 @@ + + thin-jar + + + + org.springframework.boot.experimental + spring-boot-thin-maven-plugin + ${thin.version} + + + + resolve + + resolve + + false + + + + + + diff --git a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml index 6ae6572ca9..96647ea0f1 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml +++ b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml @@ -6,10 +6,10 @@ greeter-spring-boot-autoconfigure 0.0.1-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 UTF-8 diff --git a/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml b/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml index 9db76759ec..a2c96a8555 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml +++ b/spring-boot-custom-starter/greeter-spring-boot-sample-app/pom.xml @@ -7,10 +7,10 @@ 0.0.1-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml b/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml index e771cbaa8d..7bf13eebc8 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml +++ b/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml @@ -6,10 +6,10 @@ greeter-spring-boot-starter 0.0.1-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 UTF-8 diff --git a/spring-boot-custom-starter/greeter/pom.xml b/spring-boot-custom-starter/greeter/pom.xml index 6143992088..aa45b8e6a4 100644 --- a/spring-boot-custom-starter/greeter/pom.xml +++ b/spring-boot-custom-starter/greeter/pom.xml @@ -6,9 +6,9 @@ greeter 0.0.1-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 \ No newline at end of file diff --git a/spring-boot-gradle/.gitignore b/spring-boot-gradle/.gitignore new file mode 100644 index 0000000000..192221b47d --- /dev/null +++ b/spring-boot-gradle/.gitignore @@ -0,0 +1,2 @@ +.gradle/ +build/ \ No newline at end of file diff --git a/spring-boot-gradle/build.gradle b/spring-boot-gradle/build.gradle index e602c485a9..96055536c3 100644 --- a/spring-boot-gradle/build.gradle +++ b/spring-boot-gradle/build.gradle @@ -1,12 +1,16 @@ buildscript { ext { - springBootVersion = '2.0.0.RELEASE' + springBootPlugin = 'org.springframework.boot:spring-boot-gradle-plugin' + springBootVersion = '2.0.2.RELEASE' + thinPlugin = 'org.springframework.boot.experimental:spring-boot-thin-gradle-plugin' + thinVersion = '1.0.11.RELEASE' } repositories { mavenCentral() } dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") + classpath("${springBootPlugin}:${springBootVersion}") + classpath("${thinPlugin}:${thinVersion}") } } @@ -14,6 +18,8 @@ apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' +//add tasks thinJar and thinResolve for thin JAR deployments +apply plugin: 'org.springframework.boot.experimental.thin-launcher' group = 'org.baeldung' version = '0.0.1-SNAPSHOT' @@ -23,7 +29,6 @@ repositories { mavenCentral() } - dependencies { compile('org.springframework.boot:spring-boot-starter') testCompile('org.springframework.boot:spring-boot-starter-test') @@ -42,3 +47,21 @@ bootJar { // attributes 'Start-Class': 'org.baeldung.DemoApplication' // } } + +//Enable this to generate and use a pom.xml file +apply plugin: 'maven' + +//If you want to customize the generated pom.xml you can edit this task and add it as a dependency to the bootJar task +task createPom { + def basePath = 'build/resources/main/META-INF/maven' + doLast { + pom { + withXml(dependencyManagement.pomConfigurer) + }.writeTo("${basePath}/${project.group}/${project.name}/pom.xml") + } +} +//Uncomment the following to use your custom generated pom.xml +bootJar.dependsOn = [createPom] + +//Enable this to generate and use a thin.properties file +//bootJar.dependsOn = [thinProperties] \ No newline at end of file diff --git a/spring-boot-gradle/gradle/wrapper/gradle-wrapper.properties b/spring-boot-gradle/gradle/wrapper/gradle-wrapper.properties index 44d9d03d80..a8868a918a 100644 --- a/spring-boot-gradle/gradle/wrapper/gradle-wrapper.properties +++ b/spring-boot-gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Feb 06 12:27:20 CET 2018 +#Fri Jun 01 20:39:48 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-all.zip diff --git a/spring-boot-keycloak/pom.xml b/spring-boot-keycloak/pom.xml index d2df261b2f..b7b15935ec 100644 --- a/spring-boot-keycloak/pom.xml +++ b/spring-boot-keycloak/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-boot-5 + parent-boot-1 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-boot-ops/README.md b/spring-boot-ops/README.md new file mode 100644 index 0000000000..7eca307924 --- /dev/null +++ b/spring-boot-ops/README.md @@ -0,0 +1,10 @@ +### Relevant Articles: + +- [Deploy a Spring Boot WAR into a Tomcat Server](http://www.baeldung.com/spring-boot-war-tomcat-deploy) +- [Spring Boot Dependency Management with a Custom Parent](http://www.baeldung.com/spring-boot-dependency-management-custom-parent) +- [A Custom Data Binder in Spring MVC](http://www.baeldung.com/spring-mvc-custom-data-binder) +- [Create a Fat Jar App with Spring Boot](http://www.baeldung.com/deployable-fat-jar-spring-boot) +- [Introduction to WebJars](http://www.baeldung.com/maven-webjars) +- [Intro to Spring Boot Starters](http://www.baeldung.com/spring-boot-starters) +- [A Quick Guide to Maven Wrapper](http://www.baeldung.com/maven-wrapper) +- [Shutdown a Spring Boot Application](http://www.baeldung.com/spring-boot-shutdown) diff --git a/spring-boot-ops/docker/Dockerfile b/spring-boot-ops/docker/Dockerfile new file mode 100644 index 0000000000..85db5c7bed --- /dev/null +++ b/spring-boot-ops/docker/Dockerfile @@ -0,0 +1,16 @@ +# Alpine Linux with OpenJDK JRE +FROM openjdk:8-jre-alpine +RUN apk add --no-cache bash + +# copy fat WAR +COPY spring-boot-ops.war /app.war + +# copy fat WAR +COPY logback.xml /logback.xml + +COPY run.sh /run.sh + +# runs application +#CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=default", "-Dlogging.config=/logback.xml", "/app.war"] + +ENTRYPOINT ["/run.sh"] diff --git a/spring-boot-ops/docker/logback.xml b/spring-boot-ops/docker/logback.xml new file mode 100644 index 0000000000..aad6d3fcb3 --- /dev/null +++ b/spring-boot-ops/docker/logback.xml @@ -0,0 +1,15 @@ + + + + + /var/log/WebjarsdemoApplication/application.log + true + + %-7d{yyyy-MM-dd HH:mm:ss:SSS} %m%n + + + + + + + diff --git a/spring-boot-ops/docker/run.sh b/spring-boot-ops/docker/run.sh new file mode 100755 index 0000000000..aeecc29371 --- /dev/null +++ b/spring-boot-ops/docker/run.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +java -Dspring.profiles.active=$1 -Dlogging.config=/logback.xml -jar /app.war + diff --git a/spring-boot-ops/pom.xml b/spring-boot-ops/pom.xml index b6adb27fb2..dce826dbb5 100644 --- a/spring-boot-ops/pom.xml +++ b/spring-boot-ops/pom.xml @@ -137,7 +137,7 @@ repackage - org.baeldung.boot.Application + com.baeldung.webjar.WebjarsdemoApplication diff --git a/spring-boot-property-exp/property-exp-default-config/pom.xml b/spring-boot-property-exp/property-exp-default-config/pom.xml index e4cbaebf56..0ac4a31c7c 100644 --- a/spring-boot-property-exp/property-exp-default-config/pom.xml +++ b/spring-boot-property-exp/property-exp-default-config/pom.xml @@ -8,10 +8,10 @@ jar - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-boot/README.MD b/spring-boot/README.MD index dd3f930126..595e13cd9f 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -32,3 +32,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [How to Define a Spring Boot Filter?](http://www.baeldung.com/spring-boot-add-filter) - [How to Change the Default Port in Spring Boot](http://www.baeldung.com/spring-boot-change-port) - [Spring Boot Exit Codes](http://www.baeldung.com/spring-boot-exit-codes) +- [Guide to the Favicon in Spring Boot](http://www.baeldung.com/spring-boot-favicon) diff --git a/spring-boot/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java b/spring-boot/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java new file mode 100644 index 0000000000..7cce34a06c --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.shutdownhooks; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAutoConfiguration +public class ShutdownHookApplication { + + public static void main(String args[]) { + SpringApplication.run(ShutdownHookApplication.class, args); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java b/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java new file mode 100644 index 0000000000..e85b9395d3 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java @@ -0,0 +1,14 @@ +package com.baeldung.shutdownhooks.beans; + +import javax.annotation.PreDestroy; + +import org.springframework.stereotype.Component; + +@Component +public class Bean1 { + + @PreDestroy + public void destroy() { + System.out.println("Shutdown triggered using @PreDestroy."); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java b/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java new file mode 100644 index 0000000000..e85d12e791 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java @@ -0,0 +1,14 @@ +package com.baeldung.shutdownhooks.beans; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.stereotype.Component; + +@Component +public class Bean2 implements DisposableBean { + + @Override + public void destroy() throws Exception { + System.out.println("Shutdown triggered using DisposableBean."); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java b/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java new file mode 100644 index 0000000000..bed1d50ee7 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java @@ -0,0 +1,8 @@ +package com.baeldung.shutdownhooks.beans; + +public class Bean3 { + + public void destroy() { + System.out.println("Shutdown triggered using bean destroy method."); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java b/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java new file mode 100644 index 0000000000..07d729cb83 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java @@ -0,0 +1,18 @@ +package com.baeldung.shutdownhooks.config; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +public class ExampleServletContextListener implements ServletContextListener { + + @Override + public void contextDestroyed(ServletContextEvent event) { + System.out.println("Shutdown triggered using ServletContextListener."); + } + + @Override + public void contextInitialized(ServletContextEvent event) { + // Triggers when context initializes + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java b/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java new file mode 100644 index 0000000000..2d0712e19b --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java @@ -0,0 +1,25 @@ +package com.baeldung.shutdownhooks.config; + +import javax.servlet.ServletContextListener; + +import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.shutdownhooks.beans.Bean3; + +@Configuration +public class ShutdownHookConfiguration { + + @Bean(destroyMethod = "destroy") + public Bean3 initializeBean3() { + return new Bean3(); + } + + @Bean + ServletListenerRegistrationBean servletListener() { + ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean<>(); + srb.setListener(new ExampleServletContextListener()); + return srb; + } +} diff --git a/spring-cloud-data-flow/batch-job/pom.xml b/spring-cloud-data-flow/batch-job/pom.xml index 123c4aeda6..08439065a4 100644 --- a/spring-cloud-data-flow/batch-job/pom.xml +++ b/spring-cloud-data-flow/batch-job/pom.xml @@ -12,10 +12,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-cloud-data-flow/data-flow-server/pom.xml b/spring-cloud-data-flow/data-flow-server/pom.xml index f0d513ce4d..1b81e1ba2d 100644 --- a/spring-cloud-data-flow/data-flow-server/pom.xml +++ b/spring-cloud-data-flow/data-flow-server/pom.xml @@ -12,10 +12,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-cloud-data-flow/data-flow-shell/pom.xml b/spring-cloud-data-flow/data-flow-shell/pom.xml index debbe44a4a..0166aa79c2 100644 --- a/spring-cloud-data-flow/data-flow-shell/pom.xml +++ b/spring-cloud-data-flow/data-flow-shell/pom.xml @@ -12,10 +12,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-cloud-data-flow/log-sink/pom.xml b/spring-cloud-data-flow/log-sink/pom.xml index 6e541ae3fa..ab367fadd7 100644 --- a/spring-cloud-data-flow/log-sink/pom.xml +++ b/spring-cloud-data-flow/log-sink/pom.xml @@ -12,10 +12,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-cloud-data-flow/time-processor/pom.xml b/spring-cloud-data-flow/time-processor/pom.xml index 42d0fa434f..79bae89857 100644 --- a/spring-cloud-data-flow/time-processor/pom.xml +++ b/spring-cloud-data-flow/time-processor/pom.xml @@ -12,10 +12,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-cloud-data-flow/time-source/pom.xml b/spring-cloud-data-flow/time-source/pom.xml index 2a50c9b0d0..17d2f5c693 100644 --- a/spring-cloud-data-flow/time-source/pom.xml +++ b/spring-cloud-data-flow/time-source/pom.xml @@ -12,10 +12,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-bootstrap/config/pom.xml b/spring-cloud/spring-cloud-bootstrap/config/pom.xml index ace46395c0..14a926fc2c 100644 --- a/spring-cloud/spring-cloud-bootstrap/config/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/config/pom.xml @@ -6,10 +6,10 @@ 1.0.0-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml index 7a3ffd81cd..f94d8829f6 100644 --- a/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml @@ -7,10 +7,10 @@ 1.0.0-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml index 5001b35fb5..fc69c16738 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml @@ -6,10 +6,10 @@ 1.0.0-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml b/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml index 2552752e29..c0d920d373 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml @@ -8,10 +8,10 @@ 1.0.0-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml b/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml index 857ee486c0..3aa2db8f65 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml @@ -8,10 +8,10 @@ 1.0.0-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-bootstrap/zipkin/pom.xml b/spring-cloud/spring-cloud-bootstrap/zipkin/pom.xml index 743281d346..8735e24d48 100644 --- a/spring-cloud/spring-cloud-bootstrap/zipkin/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/zipkin/pom.xml @@ -6,10 +6,10 @@ 1.0.0-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-config/pom.xml b/spring-cloud/spring-cloud-config/pom.xml index 100b421a55..0a8f4f9dc3 100644 --- a/spring-cloud/spring-cloud-config/pom.xml +++ b/spring-cloud/spring-cloud-config/pom.xml @@ -9,10 +9,10 @@ pom - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-kubernetes/pom.xml b/spring-cloud/spring-cloud-kubernetes/pom.xml index 96388c3672..61fd84ca27 100644 --- a/spring-cloud/spring-cloud-kubernetes/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/pom.xml @@ -14,10 +14,10 @@ - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 4.0.0 diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml index 8da8ef6141..664ab96576 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/pom.xml @@ -10,10 +10,10 @@ Simple books API - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml index e083986890..814f5edfcb 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/pom.xml @@ -12,10 +12,10 @@ Spring Cloud REST configuration server - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml index c7d647a154..f3ce213540 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/pom.xml @@ -10,10 +10,10 @@ Spring Cloud REST server - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml index d97ab43bfe..27e327110a 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/pom.xml @@ -10,10 +10,10 @@ Simple reviews API - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-5 + ../../../parent-boot-1 diff --git a/spring-cloud/spring-cloud-ribbon-client/pom.xml b/spring-cloud/spring-cloud-ribbon-client/pom.xml index cada10ec35..64682c6173 100644 --- a/spring-cloud/spring-cloud-ribbon-client/pom.xml +++ b/spring-cloud/spring-cloud-ribbon-client/pom.xml @@ -9,10 +9,10 @@ Introduction to Spring Cloud Rest Client with Netflix Ribbon - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-core/README.md b/spring-core/README.md index cec85534f5..3684c7f6e9 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -15,3 +15,4 @@ - [How to Inject a Property Value Into a Class Not Managed by Spring?](http://www.baeldung.com/inject-properties-value-non-spring-class) - [@Lookup Annotation in Spring](http://www.baeldung.com/spring-lookup) - [BeanNameAware and BeanFactoryAware Interfaces in Spring](http://www.baeldung.com/spring-bean-name-factory-aware) +- [Spring – Injecting Collections](http://www.baeldung.com/spring-injecting-collections) diff --git a/spring-core/src/main/java/com/baeldung/collection/BaeldungBean.java b/spring-core/src/main/java/com/baeldung/collection/BaeldungBean.java new file mode 100644 index 0000000000..6d7351df02 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/collection/BaeldungBean.java @@ -0,0 +1,18 @@ +package com.baeldung.collection; + +/** + * Created by Gebruiker on 5/22/2018. + */ +public class BaeldungBean { + + private String name; + + public BaeldungBean(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/spring-core/src/main/java/com/baeldung/collection/CollectionConfig.java b/spring-core/src/main/java/com/baeldung/collection/CollectionConfig.java new file mode 100644 index 0000000000..fbae2963e5 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/collection/CollectionConfig.java @@ -0,0 +1,50 @@ +package com.baeldung.collection; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +import java.util.*; + +@Configuration +public class CollectionConfig { + + @Bean + public CollectionsBean getCollectionsBean() { + return new CollectionsBean(new HashSet<>(Arrays.asList("John", "Adam", "Harry"))); + } + + @Bean + public List nameList(){ + return Arrays.asList("John", "Adam", "Harry", null); + } + + @Bean + public Map nameMap(){ + Map nameMap = new HashMap<>(); + nameMap.put(1, "John"); + nameMap.put(2, "Adam"); + nameMap.put(3, "Harry"); + return nameMap; + } + + @Bean + @Qualifier("CollectionsBean") + @Order(2) + public BaeldungBean getElement() { + return new BaeldungBean("John"); + } + + @Bean + @Order(3) + public BaeldungBean getAnotherElement() { + return new BaeldungBean("Adam"); + } + + @Bean + @Order(1) + public BaeldungBean getOneMoreElement() { + return new BaeldungBean("Harry"); + } +} diff --git a/spring-core/src/main/java/com/baeldung/collection/CollectionInjectionDemo.java b/spring-core/src/main/java/com/baeldung/collection/CollectionInjectionDemo.java new file mode 100644 index 0000000000..2e0d9eb8d8 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/collection/CollectionInjectionDemo.java @@ -0,0 +1,20 @@ +package com.baeldung.collection; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +/** + * Created by Gebruiker on 5/18/2018. + */ +public class CollectionInjectionDemo { + + public static void main(String[] args) { + + ApplicationContext context = new AnnotationConfigApplicationContext(CollectionConfig.class); + CollectionsBean collectionsBean = context.getBean(CollectionsBean.class); + collectionsBean.printNameList(); + collectionsBean.printNameSet(); + collectionsBean.printNameMap(); + collectionsBean.printBeanList(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/collection/CollectionsBean.java b/spring-core/src/main/java/com/baeldung/collection/CollectionsBean.java new file mode 100644 index 0000000000..a0e985267f --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/collection/CollectionsBean.java @@ -0,0 +1,54 @@ +package com.baeldung.collection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created by Gebruiker on 5/18/2018. + */ +public class CollectionsBean { + + @Autowired + private List nameList; + + private Set nameSet; + + private Map nameMap; + + @Autowired(required = false) + @Qualifier("CollectionsBean") + private List beanList = new ArrayList<>(); + + public CollectionsBean() { + } + + public CollectionsBean(Set strings) { + this.nameSet = strings; + } + + @Autowired + public void setNameMap(Map nameMap) { + this.nameMap = nameMap; + } + + public void printNameList() { + System.out.println(nameList); + } + + public void printNameSet() { + System.out.println(nameSet); + } + + public void printNameMap() { + System.out.println(nameMap); + } + + public void printBeanList() { + System.out.println(beanList); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependson/DriverApplication.java b/spring-core/src/main/java/com/baeldung/dependson/DriverApplication.java new file mode 100644 index 0000000000..166f388aa3 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependson/DriverApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.dependson; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import com.baeldung.dependson.config.Config; +import com.baeldung.dependson.file.processor.FileProcessor; + +public class DriverApplication { + public static void main(String[] args) { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class); + ctx.getBean(FileProcessor.class); + ctx.close(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependson/config/Config.java b/spring-core/src/main/java/com/baeldung/dependson/config/Config.java new file mode 100644 index 0000000000..8d96707ba6 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependson/config/Config.java @@ -0,0 +1,38 @@ +package com.baeldung.dependson.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Lazy; + +import com.baeldung.dependson.file.processor.FileProcessor; +import com.baeldung.dependson.file.reader.FileReader; +import com.baeldung.dependson.file.writer.FileWriter; +import com.baeldung.dependson.shared.File; + +@Configuration +@ComponentScan("com.baeldung.dependson") +public class Config { + + @Autowired + File file; + + @Bean("fileProcessor") + @DependsOn({"fileReader","fileWriter"}) + @Lazy + public FileProcessor fileProcessor(){ + return new FileProcessor(file); + } + + @Bean("fileReader") + public FileReader fileReader(){ + return new FileReader(file); + } + + @Bean("fileWriter") + public FileWriter fileWriter(){ + return new FileWriter(file); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependson/file/processor/FileProcessor.java b/spring-core/src/main/java/com/baeldung/dependson/file/processor/FileProcessor.java new file mode 100644 index 0000000000..f5d55dc032 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependson/file/processor/FileProcessor.java @@ -0,0 +1,19 @@ +package com.baeldung.dependson.file.processor; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.baeldung.dependson.file.reader.FileReader; +import com.baeldung.dependson.file.writer.FileWriter; +import com.baeldung.dependson.shared.File; + +public class FileProcessor { + + File file; + + public FileProcessor(File file){ + this.file = file; + if(file.getText().contains("write") && file.getText().contains("read")){ + file.setText("processed"); + } + } +} \ No newline at end of file diff --git a/spring-core/src/main/java/com/baeldung/dependson/file/reader/FileReader.java b/spring-core/src/main/java/com/baeldung/dependson/file/reader/FileReader.java new file mode 100644 index 0000000000..b6ff446534 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependson/file/reader/FileReader.java @@ -0,0 +1,12 @@ +package com.baeldung.dependson.file.reader; + +import com.baeldung.dependson.shared.File; + +public class FileReader { + + public FileReader(File file) { + file.setText("read"); + } + + public void readFile() {} +} diff --git a/spring-core/src/main/java/com/baeldung/dependson/file/writer/FileWriter.java b/spring-core/src/main/java/com/baeldung/dependson/file/writer/FileWriter.java new file mode 100644 index 0000000000..f251166c80 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependson/file/writer/FileWriter.java @@ -0,0 +1,13 @@ +package com.baeldung.dependson.file.writer; + +import com.baeldung.dependson.shared.File; + + +public class FileWriter { + + public FileWriter(File file){ + file.setText("write"); + } + + public void writeFile(){} +} diff --git a/spring-core/src/main/java/com/baeldung/dependson/shared/File.java b/spring-core/src/main/java/com/baeldung/dependson/shared/File.java new file mode 100644 index 0000000000..c1b1badc43 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependson/shared/File.java @@ -0,0 +1,17 @@ +package com.baeldung.dependson.shared; + +import org.springframework.stereotype.Service; + +@Service +public class File { + + private String text = ""; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = this.text+text; + } +} diff --git a/spring-core/src/test/java/com/baeldung/dependson/config/TestConfig.java b/spring-core/src/test/java/com/baeldung/dependson/config/TestConfig.java new file mode 100644 index 0000000000..f4b2e39ebc --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/dependson/config/TestConfig.java @@ -0,0 +1,59 @@ +package com.baeldung.dependson.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Lazy; + +import com.baeldung.dependson.file.processor.FileProcessor; +import com.baeldung.dependson.file.reader.FileReader; +import com.baeldung.dependson.file.writer.FileWriter; +import com.baeldung.dependson.shared.File; + +@Configuration +@ComponentScan("com.baeldung.dependson") +public class TestConfig { + + @Autowired + File file; + + @Bean("fileProcessor") + @DependsOn({"fileReader","fileWriter"}) + @Lazy + public FileProcessor fileProcessor(){ + return new FileProcessor(file); + } + + @Bean("fileReader") + public FileReader fileReader(){ + return new FileReader(file); + } + + @Bean("fileWriter") + public FileWriter fileWriter(){ + return new FileWriter(file); + } + + @Bean("dummyFileProcessor") + @DependsOn({"dummyfileWriter"}) + @Lazy + public FileProcessor dummyFileProcessor(){ + return new FileProcessor(file); + } + + @Bean("dummyFileProcessorCircular") + @DependsOn({"dummyFileReaderCircular"}) + @Lazy + public FileProcessor dummyFileProcessorCircular(){ + return new FileProcessor(file); + } + + @Bean("dummyFileReaderCircular") + @DependsOn({"dummyFileProcessorCircular"}) + @Lazy + public FileReader dummyFileReaderCircular(){ + return new FileReader(file); + } +} diff --git a/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java b/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java new file mode 100644 index 0000000000..11d9daf3bf --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java @@ -0,0 +1,42 @@ +package com.baeldung.dependson.processor; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.dependson.config.TestConfig; +import com.baeldung.dependson.shared.File; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = TestConfig.class) +public class FileProcessorIntegrationTest { + + @Autowired + ApplicationContext context; + + @Autowired + File file; + + @Test + public void whenAllBeansCreated_FileTextEndsWithProcessed() { + context.getBean("fileProcessor"); + assertTrue(file.getText().endsWith("processed")); + } + + @Test(expected=NoSuchBeanDefinitionException.class) + public void whenDependentBeanNotAvailable_ThrowsNoSuchBeanDefinitionException(){ + context.getBean("dummyFileProcessor"); + } + + @Test(expected=BeanCreationException.class) + public void whenCircularDependency_ThrowsBeanCreationException(){ + context.getBean("dummyFileReaderCircular"); + } +} diff --git a/spring-cucumber/pom.xml b/spring-cucumber/pom.xml index cabd1a9020..1da4c8a124 100644 --- a/spring-cucumber/pom.xml +++ b/spring-cucumber/pom.xml @@ -10,10 +10,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-custom-aop/pom.xml b/spring-custom-aop/pom.xml index 76d8e7c344..4e95d175e7 100644 --- a/spring-custom-aop/pom.xml +++ b/spring-custom-aop/pom.xml @@ -9,10 +9,10 @@ This is simple boot application for Spring boot actuator test - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-data-keyvalue/README.md b/spring-data-keyvalue/README.md new file mode 100644 index 0000000000..f76cf4d5ac --- /dev/null +++ b/spring-data-keyvalue/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [A Guide to Spring Data Key Value](http://www.baeldung.com/spring-data-key-value) diff --git a/spring-data-mongodb/README.md b/spring-data-mongodb/README.md index c2a1f703b5..4e12a2218a 100644 --- a/spring-data-mongodb/README.md +++ b/spring-data-mongodb/README.md @@ -10,3 +10,4 @@ - [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs) - [Introduction to Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-tutorial) - [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations) +- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) diff --git a/spring-data-rest-querydsl/README.md b/spring-data-rest-querydsl/README.md new file mode 100644 index 0000000000..03b5fee06a --- /dev/null +++ b/spring-data-rest-querydsl/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [REST Query Language Over Multiple Tables with Querydsl Web Support](http://www.baeldung.com/rest-querydsl-multiple-tables) diff --git a/spring-data-rest-querydsl/pom.xml b/spring-data-rest-querydsl/pom.xml new file mode 100644 index 0000000000..e4832e1552 --- /dev/null +++ b/spring-data-rest-querydsl/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + + com.baeldung + spring-data-rest-querydsl + 1.0 + + spring-data-rest-querydsl + + + org.springframework.boot + spring-boot-starter-parent + 1.5.9.RELEASE + + + + + org.springframework.boot + spring-boot-starter-data-rest + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + mysql + mysql-connector-java + + + com.querydsl + querydsl-apt + + + com.querydsl + querydsl-jpa + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + ${start-class} + ZIP + + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + -verbose + -parameters + + + + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + generate-sources + + process + + + ${project.build.directory}/generated-sources + com.querydsl.apt.jpa.JPAAnnotationProcessor + + + + + + +<<<<<<< HEAD + +======= + +>>>>>>> 19a1633c35d6d49f9c51b8ecc3dbe127c91d75c3 diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/Application.java b/spring-data-rest-querydsl/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..28d084a4dc --- /dev/null +++ b/spring-data-rest-querydsl/src/main/java/com/baeldung/Application.java @@ -0,0 +1,44 @@ +package com.baeldung; + +import com.baeldung.controller.repository.AddressRepository; +import com.baeldung.controller.repository.UserRepository; +import com.baeldung.entity.Address; +import com.baeldung.entity.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import javax.annotation.PostConstruct; + +@SpringBootApplication +@EntityScan("com.baeldung.entity") +@EnableJpaRepositories("com.baeldung.controller.repository") +@EnableAutoConfiguration +public class Application { + + @Autowired + private UserRepository personRepository; + @Autowired + private AddressRepository addressRepository; + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @PostConstruct + private void initializeData() { + // Create John + final User john = new User("John"); + personRepository.save(john); + final Address addressOne = new Address("Fake Street 1", "Spain", john); + addressRepository.save(addressOne); + // Create Lisa + final User lisa = new User("Lisa"); + personRepository.save(lisa); + final Address addressTwo = new Address("Real Street 1", "Germany", lisa); + addressRepository.save(addressTwo); + } +} diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/QueryController.java b/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/QueryController.java new file mode 100644 index 0000000000..e29932657f --- /dev/null +++ b/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/QueryController.java @@ -0,0 +1,34 @@ +package com.baeldung.controller; + +import com.baeldung.controller.repository.AddressRepository; +import com.baeldung.controller.repository.UserRepository; +import com.baeldung.entity.Address; +import com.baeldung.entity.User; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.Predicate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.querydsl.binding.QuerydslPredicate; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class QueryController { + + @Autowired + private UserRepository personRepository; + @Autowired + private AddressRepository addressRepository; + + @GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE) + public Iterable queryOverUser(@QuerydslPredicate(root = User.class) Predicate predicate) { + final BooleanBuilder builder = new BooleanBuilder(); + return personRepository.findAll(builder.and(predicate)); + } + + @GetMapping(value = "/addresses", produces = MediaType.APPLICATION_JSON_VALUE) + public Iterable
queryOverAddress(@QuerydslPredicate(root = Address.class) Predicate predicate) { + final BooleanBuilder builder = new BooleanBuilder(); + return addressRepository.findAll(builder.and(predicate)); + } +} diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/AddressRepository.java b/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/AddressRepository.java new file mode 100644 index 0000000000..2e88820c98 --- /dev/null +++ b/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/AddressRepository.java @@ -0,0 +1,19 @@ +package com.baeldung.controller.repository; + +import com.baeldung.entity.Address; +import com.baeldung.entity.QAddress; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.core.types.dsl.StringPath; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; +import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer; +import org.springframework.data.querydsl.binding.QuerydslBindings; +import org.springframework.data.querydsl.binding.SingleValueBinding; + +public interface AddressRepository + extends JpaRepository, QueryDslPredicateExecutor
, QuerydslBinderCustomizer { + @Override + default void customize(final QuerydslBindings bindings, final QAddress root) { + bindings.bind(String.class).first((SingleValueBinding) StringExpression::eq); + } +} diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/UserRepository.java b/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/UserRepository.java new file mode 100644 index 0000000000..98ff2ac5e3 --- /dev/null +++ b/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/UserRepository.java @@ -0,0 +1,19 @@ +package com.baeldung.controller.repository; + +import com.baeldung.entity.QUser; +import com.baeldung.entity.User; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.core.types.dsl.StringPath; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; +import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer; +import org.springframework.data.querydsl.binding.QuerydslBindings; +import org.springframework.data.querydsl.binding.SingleValueBinding; + +public interface UserRepository + extends JpaRepository, QueryDslPredicateExecutor, QuerydslBinderCustomizer { + @Override + default void customize(final QuerydslBindings bindings, final QUser root) { + bindings.bind(String.class).first((SingleValueBinding) StringExpression::eq); + } +} diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/Address.java b/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/Address.java new file mode 100644 index 0000000000..b01194adb7 --- /dev/null +++ b/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/Address.java @@ -0,0 +1,57 @@ +package com.baeldung.entity; + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import javax.persistence.*; + +@Entity +@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) +public class Address { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", unique = true, nullable = false) + private Long id; + @Column + private String address; + @Column + private String country; + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + public Address() { + } + + public Address(String address, String country, User user) { + this.id = id; + this.address = address; + this.country = country; + this.user = user; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } +} diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/User.java b/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/User.java new file mode 100644 index 0000000000..cfd484bb7a --- /dev/null +++ b/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/User.java @@ -0,0 +1,51 @@ +package com.baeldung.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import javax.persistence.*; + + +@Entity +@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", unique = true, nullable = false) + private Long id; + @Column + private String name; + @OneToOne(fetch = FetchType.LAZY, mappedBy = "user") + private Address address; + + public User() { + } + + public User(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/spring-data-rest-querydsl/src/main/resources/application.yml b/spring-data-rest-querydsl/src/main/resources/application.yml new file mode 100644 index 0000000000..f25c6ea0e3 --- /dev/null +++ b/spring-data-rest-querydsl/src/main/resources/application.yml @@ -0,0 +1,11 @@ +spring: + datasource: + driver-class-name: com.mysql.jdbc.Driver + hikari: + pool-name: hikari-pool + url: jdbc:mysql://localhost:3306/baeldung?verifyServerCertificate=false&useSSL=false&requireSSL=false + username: root + + jpa: + hibernate: + ddl-auto: create diff --git a/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/IntegrationTest.java b/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/IntegrationTest.java new file mode 100644 index 0000000000..ef86c2f36d --- /dev/null +++ b/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/IntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.springdatarestquerydsl; + +import com.baeldung.Application; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.nio.charset.Charset; + +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class) @WebAppConfiguration +public class IntegrationTest { + + final MediaType contentType = + new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); + + @Autowired private WebApplicationContext webApplicationContext; + + private MockMvc mockMvc; + + @Before public void setupMockMvc() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test public void givenRequestHasBeenMade_whenQueryOverNameAttribute_thenGetJohn() throws Exception { + // Get John + mockMvc.perform(get("/personQuery?name=John")).andExpect(status().isOk()).andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", hasSize(1))).andExpect(jsonPath("$[0].name", is("John"))) + .andExpect(jsonPath("$[0].address.address", is("Fake Street 1"))) + .andExpect(jsonPath("$[0].address.country", is("Fake Country"))); + } + + @Test public void givenRequestHasBeenMade_whenQueryOverNameAttribute_thenGetLisa() throws Exception { + // Get Lisa + mockMvc.perform(get("/personQuery?name=Lisa")).andExpect(status().isOk()).andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", hasSize(1))).andExpect(jsonPath("$[0].name", is("Lisa"))) + .andExpect(jsonPath("$[0].address.address", is("Real Street 1"))) + .andExpect(jsonPath("$[0].address.country", is("Real Country"))); + } +} diff --git a/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/QuerydslIntegrationTest.java b/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/QuerydslIntegrationTest.java new file mode 100644 index 0000000000..11e5ffca05 --- /dev/null +++ b/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/QuerydslIntegrationTest.java @@ -0,0 +1,65 @@ +package com.baeldung.springdatarestquerydsl; + +import com.baeldung.Application; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.nio.charset.Charset; + +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = Application.class) +@WebAppConfiguration +public class QuerydslIntegrationTest { + + final MediaType contentType = + new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); + + @Autowired + private WebApplicationContext webApplicationContext; + + private MockMvc mockMvc; + + @Before + public void setupMockMvc() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test + public void givenRequest_whenQueryUserFilteringByCountrySpain_thenGetJohn() throws Exception { + mockMvc.perform(get("/users?address.country=Spain")).andExpect(status().isOk()).andExpect(content() + .contentType + (contentType)) + .andExpect(jsonPath("$", hasSize(1))) + .andExpect(jsonPath("$[0].name", is("John"))) + .andExpect(jsonPath("$[0].address.address", is("Fake Street 1"))) + .andExpect(jsonPath("$[0].address.country", is("Spain"))); + } + + @Test + public void givenRequest_whenQueryUserWithoutFilter_thenGetJohnAndLisa() throws Exception { + mockMvc.perform(get("/users")).andExpect(status().isOk()).andExpect(content() + .contentType + (contentType)) + .andExpect(jsonPath("$", hasSize(2))) + .andExpect(jsonPath("$[0].name", is("John"))) + .andExpect(jsonPath("$[0].address.address", is("Fake Street 1"))) + .andExpect(jsonPath("$[0].address.country", is("Spain"))) + .andExpect(jsonPath("$[1].name", is("Lisa"))) + .andExpect(jsonPath("$[1].address.address", is("Real Street 1"))) + .andExpect(jsonPath("$[1].address.country", is("Germany"))); + } +} diff --git a/spring-data-rest/README.md b/spring-data-rest/README.md index 445557d10b..09f8391406 100644 --- a/spring-data-rest/README.md +++ b/spring-data-rest/README.md @@ -19,3 +19,4 @@ To view the running application, visit [http://localhost:8080](http://localhost: - [AngularJS CRUD Application with Spring Data REST](http://www.baeldung.com/angularjs-crud-with-spring-data-rest) - [List of In-Memory Databases](http://www.baeldung.com/java-in-memory-databases) - [Projections and Excerpts in Spring Data REST](http://www.baeldung.com/spring-data-rest-projections-excerpts) +- [Spring Data REST Events with @RepositoryEventHandler](http://www.baeldung.com/spring-data-rest-events) diff --git a/spring-data-rest/pom.xml b/spring-data-rest/pom.xml index bad7a38281..0e525474e3 100644 --- a/spring-data-rest/pom.xml +++ b/spring-data-rest/pom.xml @@ -10,10 +10,10 @@ Intro to Spring Data REST - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-data-spring-security/pom.xml b/spring-data-spring-security/pom.xml index afdf3c332c..467c38284d 100644 --- a/spring-data-spring-security/pom.xml +++ b/spring-data-spring-security/pom.xml @@ -11,10 +11,10 @@ Spring Data with Spring Security - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-ejb/spring-ejb-client/pom.xml b/spring-ejb/spring-ejb-client/pom.xml index f7b42212be..941105a220 100644 --- a/spring-ejb/spring-ejb-client/pom.xml +++ b/spring-ejb/spring-ejb-client/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-boot-5 + parent-boot-1 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index c43952e277..6d26d18f96 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -9,10 +9,10 @@ Intro to Jenkins 2 and the power of pipelines - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-kafka/pom.xml b/spring-kafka/pom.xml index 3891be1ec3..db0d7e6df9 100644 --- a/spring-kafka/pom.xml +++ b/spring-kafka/pom.xml @@ -8,10 +8,10 @@ Intro to Kafka with Spring - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-katharsis/pom.xml b/spring-katharsis/pom.xml index 27075de747..6addb614f5 100644 --- a/spring-katharsis/pom.xml +++ b/spring-katharsis/pom.xml @@ -7,10 +7,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 @@ -33,7 +33,7 @@ io.katharsis - katharsis-servlet + katharsis-spring ${katharsis.version} diff --git a/spring-katharsis/src/main/java/org/baeldung/Application.java b/spring-katharsis/src/main/java/org/baeldung/Application.java index ee072305d8..5ce4ac7e08 100644 --- a/spring-katharsis/src/main/java/org/baeldung/Application.java +++ b/spring-katharsis/src/main/java/org/baeldung/Application.java @@ -1,10 +1,14 @@ package org.baeldung; +import io.katharsis.spring.boot.v3.KatharsisConfigV3; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Import; @SpringBootApplication +@Import(KatharsisConfigV3.class) public class Application extends SpringBootServletInitializer { public static void main(String[] args) { diff --git a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/JsonApiFilter.java b/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/JsonApiFilter.java deleted file mode 100644 index 3d0d441357..0000000000 --- a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/JsonApiFilter.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.baeldung.persistence.katharsis; - -import io.katharsis.invoker.internal.legacy.KatharsisInvokerBuilder; -import io.katharsis.legacy.locator.JsonServiceLocator; -import io.katharsis.servlet.legacy.AbstractKatharsisFilter; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.stereotype.Component; - -@Component -public class JsonApiFilter extends AbstractKatharsisFilter implements BeanFactoryAware { - - private static final String DEFAULT_RESOURCE_SEARCH_PACKAGE = "org.baeldung.persistence"; - - private static final String RESOURCE_DEFAULT_DOMAIN = "http://localhost:8080"; - - private BeanFactory beanFactory; - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - - @Override - protected KatharsisInvokerBuilder createKatharsisInvokerBuilder() { - final KatharsisInvokerBuilder builder = new KatharsisInvokerBuilder(); - - builder.resourceSearchPackage(DEFAULT_RESOURCE_SEARCH_PACKAGE).resourceDefaultDomain(RESOURCE_DEFAULT_DOMAIN).jsonServiceLocator(new JsonServiceLocator() { - @Override - public T getInstance(Class clazz) { - return beanFactory.getBean(clazz); - } - }); - - return builder; - } - -} diff --git a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/RoleResourceRepository.java b/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/RoleResourceRepository.java index 52ca40e26e..1998c414bb 100644 --- a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/RoleResourceRepository.java +++ b/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/RoleResourceRepository.java @@ -1,7 +1,9 @@ package org.baeldung.persistence.katharsis; -import io.katharsis.legacy.queryParams.QueryParams; -import io.katharsis.legacy.repository.ResourceRepository; + +import io.katharsis.queryspec.QuerySpec; +import io.katharsis.repository.ResourceRepositoryV2; +import io.katharsis.resource.list.ResourceList; import org.baeldung.persistence.dao.RoleRepository; import org.baeldung.persistence.model.Role; @@ -9,23 +11,23 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component -public class RoleResourceRepository implements ResourceRepository { +public class RoleResourceRepository implements ResourceRepositoryV2 { @Autowired private RoleRepository roleRepository; @Override - public Role findOne(Long id, QueryParams params) { + public Role findOne(Long id, QuerySpec querySpec) { return roleRepository.findOne(id); } @Override - public Iterable findAll(QueryParams params) { - return roleRepository.findAll(); + public ResourceList findAll(QuerySpec querySpec) { + return querySpec.apply(roleRepository.findAll()); } @Override - public Iterable findAll(Iterable ids, QueryParams params) { - return roleRepository.findAll(ids); + public ResourceList findAll(Iterable ids, QuerySpec querySpec) { + return querySpec.apply(roleRepository.findAll(ids)); } @Override @@ -38,4 +40,14 @@ public class RoleResourceRepository implements ResourceRepository { roleRepository.delete(id); } + @Override + public Class getResourceClass() { + return Role.class; + } + + @Override + public S create(S entity) { + return save(entity); + } + } diff --git a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserResourceRepository.java b/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserResourceRepository.java index a36c3c3c0a..9b3de31601 100644 --- a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserResourceRepository.java +++ b/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserResourceRepository.java @@ -1,7 +1,8 @@ package org.baeldung.persistence.katharsis; -import io.katharsis.legacy.queryParams.QueryParams; -import io.katharsis.legacy.repository.ResourceRepository; +import io.katharsis.queryspec.QuerySpec; +import io.katharsis.repository.ResourceRepositoryV2; +import io.katharsis.resource.list.ResourceList; import org.baeldung.persistence.dao.UserRepository; import org.baeldung.persistence.model.User; @@ -9,24 +10,24 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component -public class UserResourceRepository implements ResourceRepository { +public class UserResourceRepository implements ResourceRepositoryV2 { @Autowired private UserRepository userRepository; @Override - public User findOne(Long id, QueryParams params) { + public User findOne(Long id, QuerySpec querySpec) { return userRepository.findOne(id); } @Override - public Iterable findAll(QueryParams params) { - return userRepository.findAll(); + public ResourceList findAll(QuerySpec querySpec) { + return querySpec.apply(userRepository.findAll()); } @Override - public Iterable findAll(Iterable ids, QueryParams params) { - return userRepository.findAll(ids); + public ResourceList findAll(Iterable ids, QuerySpec querySpec) { + return querySpec.apply(userRepository.findAll(ids)); } @Override @@ -39,4 +40,14 @@ public class UserResourceRepository implements ResourceRepository { userRepository.delete(id); } + @Override + public Class getResourceClass() { + return User.class; + } + + @Override + public S create(S entity) { + return save(entity); + } + } diff --git a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserToRoleRelationshipRepository.java b/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserToRoleRelationshipRepository.java index 19007a285f..dbeb769fac 100644 --- a/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserToRoleRelationshipRepository.java +++ b/spring-katharsis/src/main/java/org/baeldung/persistence/katharsis/UserToRoleRelationshipRepository.java @@ -1,7 +1,8 @@ package org.baeldung.persistence.katharsis; -import io.katharsis.legacy.queryParams.QueryParams; -import io.katharsis.legacy.repository.RelationshipRepository; +import io.katharsis.queryspec.QuerySpec; +import io.katharsis.repository.RelationshipRepositoryV2; +import io.katharsis.resource.list.ResourceList; import java.util.HashSet; import java.util.Set; @@ -14,7 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component -public class UserToRoleRelationshipRepository implements RelationshipRepository { +public class UserToRoleRelationshipRepository implements RelationshipRepositoryV2 { @Autowired private UserRepository userRepository; @@ -52,14 +53,25 @@ public class UserToRoleRelationshipRepository implements RelationshipRepository< } @Override - public Role findOneTarget(Long sourceId, String fieldName, QueryParams QueryParams) { + public Role findOneTarget(Long sourceId, String fieldName, QuerySpec querySpec) { // not for many-to-many return null; } @Override - public Iterable findManyTargets(Long sourceId, String fieldName, QueryParams QueryParams) { + public ResourceList findManyTargets(Long sourceId, String fieldName, QuerySpec querySpec) { final User user = userRepository.findOne(sourceId); - return user.getRoles(); + return querySpec.apply(user.getRoles()); } + + @Override + public Class getSourceResourceClass() { + return User.class; + } + + @Override + public Class getTargetResourceClass() { + return Role.class; + } + } diff --git a/spring-katharsis/src/main/java/org/baeldung/persistence/model/Role.java b/spring-katharsis/src/main/java/org/baeldung/persistence/model/Role.java index fcaf40ac2c..f391efd37c 100644 --- a/spring-katharsis/src/main/java/org/baeldung/persistence/model/Role.java +++ b/spring-katharsis/src/main/java/org/baeldung/persistence/model/Role.java @@ -1,8 +1,8 @@ package org.baeldung.persistence.model; import io.katharsis.resource.annotations.JsonApiId; +import io.katharsis.resource.annotations.JsonApiRelation; import io.katharsis.resource.annotations.JsonApiResource; -import io.katharsis.resource.annotations.JsonApiToMany; import java.util.Set; @@ -25,7 +25,7 @@ public class Role { private String name; @ManyToMany(mappedBy = "roles") - @JsonApiToMany + @JsonApiRelation private Set users; // @@ -66,23 +66,30 @@ public class Role { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } final Role other = (Role) obj; if (id == null) { - if (other.id != null) + if (other.id != null) { return false; - } else if (!id.equals(other.id)) + } + } else if (!id.equals(other.id)) { return false; + } if (name == null) { - if (other.name != null) + if (other.name != null) { return false; - } else if (!name.equals(other.name)) + } + } else if (!name.equals(other.name)) { return false; + } return true; } diff --git a/spring-katharsis/src/main/java/org/baeldung/persistence/model/User.java b/spring-katharsis/src/main/java/org/baeldung/persistence/model/User.java index 58a92002c8..7c55e29599 100644 --- a/spring-katharsis/src/main/java/org/baeldung/persistence/model/User.java +++ b/spring-katharsis/src/main/java/org/baeldung/persistence/model/User.java @@ -1,9 +1,9 @@ package org.baeldung.persistence.model; import io.katharsis.resource.annotations.JsonApiId; -import io.katharsis.resource.annotations.JsonApiIncludeByDefault; +import io.katharsis.resource.annotations.JsonApiRelation; import io.katharsis.resource.annotations.JsonApiResource; -import io.katharsis.resource.annotations.JsonApiToMany; +import io.katharsis.resource.annotations.SerializeType; import java.util.Set; @@ -31,8 +31,7 @@ public class User { @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")) - @JsonApiToMany - @JsonApiIncludeByDefault + @JsonApiRelation(serialize=SerializeType.EAGER) private Set roles; public User() { @@ -87,15 +86,19 @@ public class User { @Override public boolean equals(final Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } final User user = (User) obj; - if (!email.equals(user.email)) + if (!email.equals(user.email)) { return false; + } return true; } diff --git a/spring-katharsis/src/main/resources/application.properties b/spring-katharsis/src/main/resources/application.properties index b55fdbba03..120b3c62ee 100644 --- a/spring-katharsis/src/main/resources/application.properties +++ b/spring-katharsis/src/main/resources/application.properties @@ -6,4 +6,7 @@ spring.jpa.hibernate.ddl-auto = create-drop spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect server.port=8082 -server.context-path=/spring-katharsis \ No newline at end of file +server.context-path=/spring-katharsis + +katharsis.domainName=http://localhost:8082/spring-katharsis +katharsis.pathPrefix=/ \ No newline at end of file diff --git a/spring-mobile/pom.xml b/spring-mobile/pom.xml index 6916bb9320..3d47bb106b 100644 --- a/spring-mobile/pom.xml +++ b/spring-mobile/pom.xml @@ -11,10 +11,10 @@ http://maven.apache.org - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-mockito/README.md b/spring-mockito/README.md index 3ced7161fa..969954c15e 100644 --- a/spring-mockito/README.md +++ b/spring-mockito/README.md @@ -5,3 +5,4 @@ ### Relevant Articles: - [Injecting Mockito Mocks into Spring Beans](http://www.baeldung.com/injecting-mocks-in-spring) +- [Mockito ArgumentMatchers](http://www.baeldung.com/mockito-argument-matchers) diff --git a/spring-mockito/pom.xml b/spring-mockito/pom.xml index 63a5521c98..e27e25b4c8 100644 --- a/spring-mockito/pom.xml +++ b/spring-mockito/pom.xml @@ -12,16 +12,16 @@ Injecting Mockito Mocks into Spring Beans - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 org.springframework.boot - spring-boot-starter + spring-boot-starter-web org.mockito diff --git a/spring-mockito/src/main/java/com/baeldung/app/api/Flower.java b/spring-mockito/src/main/java/com/baeldung/app/api/Flower.java new file mode 100644 index 0000000000..dc1c36e3ff --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/app/api/Flower.java @@ -0,0 +1,28 @@ +package com.baeldung.app.api; + +public class Flower { + + private String name; + private Integer petals; + + public Flower(String name, Integer petals) { + this.name = name; + this.petals = petals; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getPetals() { + return petals; + } + + public void setPetals(Integer petals) { + this.petals = petals; + } +} diff --git a/spring-mockito/src/main/java/com/baeldung/app/api/MessageApi.java b/spring-mockito/src/main/java/com/baeldung/app/api/MessageApi.java new file mode 100644 index 0000000000..edbe5a1d5a --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/app/api/MessageApi.java @@ -0,0 +1,31 @@ +package com.baeldung.app.api; + +public class MessageApi { + private String from; + private String to; + private String text; + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } +} diff --git a/spring-mockito/src/main/java/com/baeldung/app/rest/FlowerController.java b/spring-mockito/src/main/java/com/baeldung/app/rest/FlowerController.java new file mode 100644 index 0000000000..b3d8888cec --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/app/rest/FlowerController.java @@ -0,0 +1,27 @@ +package com.baeldung.app.rest; + +import com.baeldung.app.api.Flower; +import com.baeldung.domain.service.FlowerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/flowers") +public class FlowerController { + + @Autowired + private FlowerService flowerService; + + @PostMapping("/isAFlower") + public String isAFlower (@RequestBody String flower) { + return flowerService.analize(flower); + } + + @PostMapping("/isABigFlower") + public Boolean isABigFlower (@RequestBody Flower flower) { + return flowerService.isABigFlower(flower.getName(), flower.getPetals()); + } +} diff --git a/spring-mockito/src/main/java/com/baeldung/app/rest/MessageController.java b/spring-mockito/src/main/java/com/baeldung/app/rest/MessageController.java new file mode 100644 index 0000000000..e23c2e7607 --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/app/rest/MessageController.java @@ -0,0 +1,34 @@ +package com.baeldung.app.rest; + +import com.baeldung.app.api.MessageApi; +import com.baeldung.domain.model.Message; +import com.baeldung.domain.service.MessageService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.time.Instant; +import java.util.Date; +import java.util.UUID; + +@Controller +@RequestMapping("/message") +public class MessageController { + + @Autowired + private MessageService messageService; + + @PostMapping + public Message createMessage (@RequestBody MessageApi messageDTO) { + Message message = new Message(); + message.setText(messageDTO.getText()); + message.setFrom(messageDTO.getFrom()); + message.setTo(messageDTO.getTo()); + message.setDate(Date.from(Instant.now())); + message.setId(UUID.randomUUID()); + + return messageService.deliverMessage(message); + } +} diff --git a/spring-mockito/src/main/java/com/baeldung/domain/model/Message.java b/spring-mockito/src/main/java/com/baeldung/domain/model/Message.java new file mode 100644 index 0000000000..a516d5619b --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/domain/model/Message.java @@ -0,0 +1,53 @@ +package com.baeldung.domain.model; + +import java.util.Date; +import java.util.UUID; + +public class Message { + + private String from; + private String to; + private String text; + private Date date; + private UUID id; + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } +} diff --git a/spring-mockito/src/main/java/com/baeldung/domain/service/FlowerService.java b/spring-mockito/src/main/java/com/baeldung/domain/service/FlowerService.java new file mode 100644 index 0000000000..3c76cb5d76 --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/domain/service/FlowerService.java @@ -0,0 +1,28 @@ +package com.baeldung.domain.service; + +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +@Service +public class FlowerService { + + private List flowers = Arrays.asList("Poppy", "Ageratum", "Carnation", "Diascia", "Lantana"); + + public String analize(String name) { + if(flowers.contains(name)) { + return "flower"; + } + return null; + } + + public boolean isABigFlower(String name, int petals) { + if(flowers.contains(name)) { + if(petals > 10) { + return true; + } + } + return false; + } +} diff --git a/spring-mockito/src/main/java/com/baeldung/domain/service/MessageService.java b/spring-mockito/src/main/java/com/baeldung/domain/service/MessageService.java new file mode 100644 index 0000000000..d156c59571 --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/domain/service/MessageService.java @@ -0,0 +1,13 @@ +package com.baeldung.domain.service; + +import com.baeldung.domain.model.Message; +import org.springframework.stereotype.Service; + +@Service +public class MessageService { + + public Message deliverMessage (Message message) { + + return message; + } +} diff --git a/spring-mockito/src/main/java/com/baeldung/domain/util/MessageMatcher.java b/spring-mockito/src/main/java/com/baeldung/domain/util/MessageMatcher.java new file mode 100644 index 0000000000..05cb43e4df --- /dev/null +++ b/spring-mockito/src/main/java/com/baeldung/domain/util/MessageMatcher.java @@ -0,0 +1,27 @@ +package com.baeldung.domain.util; + +import com.baeldung.domain.model.Message; +import org.mockito.ArgumentMatcher; + +public class MessageMatcher extends ArgumentMatcher { + + private Message left; + + public MessageMatcher(Message message) { + this.left = message; + } + + @Override + public boolean matches(Object object) { + if (object instanceof Message) { + Message right = (Message) object; + return left.getFrom().equals(right.getFrom()) && + left.getTo().equals(right.getTo()) && + left.getText().equals(right.getText()) && + right.getDate() != null && + right.getId() != null; + } + + return false; + } +} \ No newline at end of file diff --git a/spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationTest.java b/spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationUnitTest.java similarity index 95% rename from spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationTest.java rename to spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationUnitTest.java index d70f916b12..573a37a9a4 100644 --- a/spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationTest.java +++ b/spring-mockito/src/test/java/com/baeldung/UserServiceIntegrationUnitTest.java @@ -12,7 +12,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ActiveProfiles("test") @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = MocksApplication.class) -public class UserServiceIntegrationTest { +public class UserServiceIntegrationUnitTest { @Autowired private UserService userService; diff --git a/spring-mockito/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java b/spring-mockito/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java new file mode 100644 index 0000000000..f30af140af --- /dev/null +++ b/spring-mockito/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.app.rest; + +import com.baeldung.app.api.Flower; +import com.baeldung.domain.service.FlowerService; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class FlowerControllerUnitTest { + + @Mock + private FlowerService flowerService; + + @InjectMocks + private FlowerController flowerController; + + @Test + public void isAFlower_withMockito_OK() { + when(flowerService.analize(eq("violetta"))).thenReturn("Flower"); + + String response = flowerController.isAFlower("violetta"); + + Assert.assertEquals("Flower", response); + } + + @Test + public void isABigFlower_withMockito_OK() { + when(flowerService.isABigFlower(eq("violetta"), anyInt())).thenReturn(true); + + Flower flower = new Flower("violetta", 15); + + Boolean response = flowerController.isABigFlower(flower); + + Assert.assertTrue(response); + } +} diff --git a/spring-mockito/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java b/spring-mockito/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java new file mode 100644 index 0000000000..e303c85caf --- /dev/null +++ b/spring-mockito/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.app.rest; + +import com.baeldung.app.api.MessageApi; +import com.baeldung.domain.model.Message; +import com.baeldung.domain.service.MessageService; +import com.baeldung.domain.util.MessageMatcher; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.mockito.Mockito.times; + +@RunWith(MockitoJUnitRunner.class) +public class MessageControllerUnitTest { + + @Mock + private MessageService messageService; + + @InjectMocks + private MessageController messageController; + + @Test + public void createMessage_NewMessage_OK() { + MessageApi messageApi = new MessageApi(); + messageApi.setFrom("me"); + messageApi.setTo("you"); + messageApi.setText("Hello, you!"); + + messageController.createMessage(messageApi); + + Message message = new Message(); + message.setFrom("me"); + message.setTo("you"); + message.setText("Hello, you!"); + + Mockito.verify(messageService, times(1)).deliverMessage(Matchers.argThat(new MessageMatcher(message))); + } +} diff --git a/spring-mvc-email/pom.xml b/spring-mvc-email/pom.xml index 436b4155fa..40d83046ef 100644 --- a/spring-mvc-email/pom.xml +++ b/spring-mvc-email/pom.xml @@ -10,10 +10,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-mvc-forms-thymeleaf/pom.xml b/spring-mvc-forms-thymeleaf/pom.xml index 408e7643d2..59130a0133 100644 --- a/spring-mvc-forms-thymeleaf/pom.xml +++ b/spring-mvc-forms-thymeleaf/pom.xml @@ -69,6 +69,7 @@ UTF-8 UTF-8 3.0.9.RELEASE + com.baeldung.sessionattrs.SessionAttrsApplication diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java new file mode 100644 index 0000000000..823ff436fb --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java @@ -0,0 +1,73 @@ +package com.baeldung.listbindingexample; + +public class Book { + + private long id; + + private String title; + + private String author; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((author == null) ? 0 : author.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((title == null) ? 0 : title.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Book other = (Book) obj; + if (author == null) { + if (other.author != null) + return false; + } else if (!author.equals(other.author)) + return false; + if (id != other.id) + return false; + if (title == null) { + if (other.title != null) + return false; + } else if (!title.equals(other.title)) + return false; + return true; + } + + @Override + public String toString() { + return "Book [id=" + id + ", title=" + title + ", author=" + author + "]"; + } +} diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java new file mode 100644 index 0000000000..770e86ad68 --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java @@ -0,0 +1,10 @@ +package com.baeldung.listbindingexample; + +import java.util.List; + +public interface BookService { + + List findAll(); + + void saveAll(List books); +} diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java new file mode 100644 index 0000000000..8e5654143a --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java @@ -0,0 +1,29 @@ +package com.baeldung.listbindingexample; + +import java.util.ArrayList; +import java.util.List; + +public class BooksCreationDto { + + private List books; + + public BooksCreationDto() { + this.books = new ArrayList<>(); + } + + public BooksCreationDto(List books) { + this.books = books; + } + + public List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } + + public void addBook(Book book) { + this.books.add(book); + } +} diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java new file mode 100644 index 0000000000..ffba2cea2c --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java @@ -0,0 +1,33 @@ +package com.baeldung.listbindingexample; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; +import org.thymeleaf.templateresolver.ITemplateResolver; + +@EnableWebMvc +@Configuration +public class Config implements WebMvcConfigurer { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("index"); + registry.setOrder(Ordered.HIGHEST_PRECEDENCE); + } + + @Bean + public ITemplateResolver templateResolver() { + ClassLoaderTemplateResolver resolver + = new ClassLoaderTemplateResolver(); + resolver.setPrefix("templates/books/"); + resolver.setSuffix(".html"); + resolver.setTemplateMode(TemplateMode.HTML); + resolver.setCharacterEncoding("UTF-8"); + return resolver; + } +} diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java new file mode 100644 index 0000000000..56ca41c51f --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java @@ -0,0 +1,44 @@ +package com.baeldung.listbindingexample; + +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class InMemoryBookService implements BookService { + + static Map booksDB = new HashMap<>(); + + @Override + public List findAll() { + return new ArrayList(booksDB.values()); + } + + @Override + public void saveAll(List books) { + long nextId = getNextId(); + for (Book book : books) { + if (book.getId() == 0) { + book.setId(nextId++); + } + } + + Map bookMap = books.stream() + .collect(Collectors.toMap( + Book::getId, Function.identity())); + + booksDB.putAll(bookMap); + } + + private Long getNextId(){ + return booksDB.keySet().stream() + .mapToLong(value -> value) + .max() + .orElse(0) + 1; + } +} diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java new file mode 100644 index 0000000000..af8608704b --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.listbindingexample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication( + exclude = {SecurityAutoConfiguration.class, + DataSourceAutoConfiguration.class}) +public class ListBindingApplication { + + public static void main(String[] args) { + SpringApplication.run(ListBindingApplication.class, args); + } +} diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java new file mode 100644 index 0000000000..2e177c7bbf --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java @@ -0,0 +1,59 @@ +package com.baeldung.listbindingexample; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.ArrayList; +import java.util.List; + +@Controller +@RequestMapping("/books") +public class MultipleBooksController { + + @Autowired + private BookService bookService; + + @GetMapping(value = "/all") + public String showAll(Model model) { + model.addAttribute("books", bookService.findAll()); + + return "allBooks"; + } + + @GetMapping(value = "/create") + public String showCreateForm(Model model) { + BooksCreationDto booksForm = new BooksCreationDto(); + + for (int i = 1; i <= 3; i++) { + booksForm.addBook(new Book()); + } + + model.addAttribute("form", booksForm); + + return "createBooksForm"; + } + + @GetMapping(value = "/edit") + public String showEditForm(Model model) { + List books = new ArrayList<>(); + bookService.findAll().iterator().forEachRemaining(books::add); + + model.addAttribute("form", new BooksCreationDto(books)); + + return "editBooksForm"; + } + + @PostMapping(value = "/save") + public String saveBooks(@ModelAttribute BooksCreationDto form, Model model) { + bookService.saveAll(form.getBooks()); + + model.addAttribute("books", bookService.findAll()); + + return "redirect:/books/all"; + } +} diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html new file mode 100644 index 0000000000..9f75bec8bd --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html @@ -0,0 +1,40 @@ + + + All Books + + + +
+
+
+

Books

+
+
+
+
+ + + + + + + + + + + + + + + + +
Title Author
No Books Available
Title Author
+
+ +
+
+ + diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html new file mode 100644 index 0000000000..9f88762882 --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html @@ -0,0 +1,45 @@ + + + Add Books + + + +
+
+
+

Add Books

+
+
+
+
+ Back to All Books +
+
+ + + + + + + + + + + + + + + + + +
Title Author
+
+
+
+
+
+ + diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html new file mode 100644 index 0000000000..9278d98018 --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html @@ -0,0 +1,49 @@ + + + Edit Books + + + +
+
+
+

Add Books

+
+
+
+
+ Back to All Books +
+
+ + + + + + + + + + + + + + + + + + + +
Title Author
+
+
+
+
+
+ + diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html new file mode 100644 index 0000000000..59780b84aa --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html @@ -0,0 +1,22 @@ + + + + Binding a List in Thymeleaf + + + + + + + +
+

+

Binding a List in Thymeleaf - Example

+

+
+ + + diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 1fd416d19f..b97b961e60 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -28,3 +28,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [The Spring @Controller and @RestController Annotations](http://www.baeldung.com/spring-controller-vs-restcontroller) - [Spring MVC @PathVariable with a dot (.) gets truncated](http://www.baeldung.com/spring-mvc-pathvariable-dot) - [A Quick Example of Spring Websockets’ @SendToUser Annotation](http://www.baeldung.com/spring-websockets-sendtouser) +- [Spring Boot Annotations](http://www.baeldung.com/spring-boot-annotations) +- [Spring Scheduling Annotations](http://www.baeldung.com/spring-scheduling-annotations) +- [Spring Web Annotations](http://www.baeldung.com/spring-mvc-annotations) +- [Spring Core Annotations](http://www.baeldung.com/spring-core-annotations) diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml index f8d1d32f63..bc81a89bec 100644 --- a/spring-mvc-java/pom.xml +++ b/spring-mvc-java/pom.xml @@ -7,10 +7,10 @@ spring-mvc-java - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-protobuf/pom.xml b/spring-protobuf/pom.xml index 5081634d9b..1dce122f27 100644 --- a/spring-protobuf/pom.xml +++ b/spring-protobuf/pom.xml @@ -7,10 +7,10 @@ spring-protobuf - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-quartz/pom.xml b/spring-quartz/pom.xml index 435e571180..2a449ce494 100644 --- a/spring-quartz/pom.xml +++ b/spring-quartz/pom.xml @@ -11,10 +11,10 @@ Demo project for Scheduling in Spring with Quartz - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-reactor/pom.xml b/spring-reactor/pom.xml index 1098f8b60d..cedaa5e381 100644 --- a/spring-reactor/pom.xml +++ b/spring-reactor/pom.xml @@ -9,10 +9,10 @@ http://maven.apache.org - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-remoting/pom.xml b/spring-remoting/pom.xml index aac8357c10..150c1a771c 100644 --- a/spring-remoting/pom.xml +++ b/spring-remoting/pom.xml @@ -11,10 +11,10 @@ Parent for all projects related to Spring Remoting. - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-rest-angular/pom.xml b/spring-rest-angular/pom.xml index 7f3c21801c..090f09de3b 100644 --- a/spring-rest-angular/pom.xml +++ b/spring-rest-angular/pom.xml @@ -9,10 +9,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-rest-full/pom.xml b/spring-rest-full/pom.xml index fd2c485eaf..2beff519c0 100644 --- a/spring-rest-full/pom.xml +++ b/spring-rest-full/pom.xml @@ -9,10 +9,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-rest-query-language/pom.xml b/spring-rest-query-language/pom.xml index d20a97268b..c16c6b583d 100644 --- a/spring-rest-query-language/pom.xml +++ b/spring-rest-query-language/pom.xml @@ -9,10 +9,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-rest/README.md b/spring-rest/README.md index c1183b500a..d1dcf554a5 100644 --- a/spring-rest/README.md +++ b/spring-rest/README.md @@ -22,4 +22,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Guide to DeferredResult in Spring](http://www.baeldung.com/spring-deferred-result) - [Spring Custom Property Editor](http://www.baeldung.com/spring-mvc-custom-property-editor) - [Using the Spring RestTemplate Interceptor](http://www.baeldung.com/spring-rest-template-interceptor) +- [Configure a RestTemplate with RestTemplateBuilder](http://www.baeldung.com/spring-rest-template-builder) diff --git a/spring-security-acl/pom.xml b/spring-security-acl/pom.xml index 7ddbf66365..88502bd268 100644 --- a/spring-security-acl/pom.xml +++ b/spring-security-acl/pom.xml @@ -11,10 +11,10 @@ Spring Security ACL - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-security-cache-control/pom.xml b/spring-security-cache-control/pom.xml index 890ff5bd3f..85b8b5a203 100644 --- a/spring-security-cache-control/pom.xml +++ b/spring-security-cache-control/pom.xml @@ -8,10 +8,10 @@ 1.0-SNAPSHOT - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-security-client/spring-security-jsp-authentication/pom.xml b/spring-security-client/spring-security-jsp-authentication/pom.xml index 9b1ebc6fdc..637fd3dbdb 100644 --- a/spring-security-client/spring-security-jsp-authentication/pom.xml +++ b/spring-security-client/spring-security-jsp-authentication/pom.xml @@ -12,10 +12,10 @@ Spring Security JSP Authentication tag sample - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-security-client/spring-security-jsp-authorize/pom.xml b/spring-security-client/spring-security-jsp-authorize/pom.xml index ee8c9bacbd..94f70ed5f0 100644 --- a/spring-security-client/spring-security-jsp-authorize/pom.xml +++ b/spring-security-client/spring-security-jsp-authorize/pom.xml @@ -12,10 +12,10 @@ Spring Security JSP Authorize tag sample - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-security-client/spring-security-jsp-config/pom.xml b/spring-security-client/spring-security-jsp-config/pom.xml index 0ec72c3527..54dc2fe947 100644 --- a/spring-security-client/spring-security-jsp-config/pom.xml +++ b/spring-security-client/spring-security-jsp-config/pom.xml @@ -12,10 +12,10 @@ Spring Security JSP configuration - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-security-client/spring-security-mvc/pom.xml b/spring-security-client/spring-security-mvc/pom.xml index a6c3065cc8..5064aec7e8 100644 --- a/spring-security-client/spring-security-mvc/pom.xml +++ b/spring-security-client/spring-security-mvc/pom.xml @@ -12,10 +12,10 @@ Spring Security MVC - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-security-client/spring-security-thymeleaf-authentication/pom.xml b/spring-security-client/spring-security-thymeleaf-authentication/pom.xml index 345daa9570..7bea8124e7 100644 --- a/spring-security-client/spring-security-thymeleaf-authentication/pom.xml +++ b/spring-security-client/spring-security-thymeleaf-authentication/pom.xml @@ -12,10 +12,10 @@ Spring Security thymeleaf authentication tag sample - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-security-client/spring-security-thymeleaf-authorize/pom.xml b/spring-security-client/spring-security-thymeleaf-authorize/pom.xml index 3e66e9f613..b03464877a 100644 --- a/spring-security-client/spring-security-thymeleaf-authorize/pom.xml +++ b/spring-security-client/spring-security-thymeleaf-authorize/pom.xml @@ -12,10 +12,10 @@ Spring Security thymeleaf authorize tag sample - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-security-client/spring-security-thymeleaf-config/pom.xml b/spring-security-client/spring-security-thymeleaf-config/pom.xml index f5d4306754..3abe9d8c8b 100644 --- a/spring-security-client/spring-security-thymeleaf-config/pom.xml +++ b/spring-security-client/spring-security-thymeleaf-config/pom.xml @@ -12,10 +12,10 @@ Spring Security thymeleaf configuration sample project - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../../parent-boot-1 diff --git a/spring-security-core/pom.xml b/spring-security-core/pom.xml index 27c6741790..a11743d9fa 100644 --- a/spring-security-core/pom.xml +++ b/spring-security-core/pom.xml @@ -9,10 +9,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-security-mvc-ldap/pom.xml b/spring-security-mvc-ldap/pom.xml index 286b189d87..6a9aa5eebe 100644 --- a/spring-security-mvc-ldap/pom.xml +++ b/spring-security-mvc-ldap/pom.xml @@ -9,10 +9,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-security-rest-custom/pom.xml b/spring-security-rest-custom/pom.xml index cfa3ad4b99..1ee324bcdb 100644 --- a/spring-security-rest-custom/pom.xml +++ b/spring-security-rest-custom/pom.xml @@ -9,10 +9,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-security-sso/pom.xml b/spring-security-sso/pom.xml index 938636ff18..f68b9addac 100644 --- a/spring-security-sso/pom.xml +++ b/spring-security-sso/pom.xml @@ -9,10 +9,10 @@ pom - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-security-stormpath/pom.xml b/spring-security-stormpath/pom.xml index 17973165ea..71a7123c2c 100644 --- a/spring-security-stormpath/pom.xml +++ b/spring-security-stormpath/pom.xml @@ -9,10 +9,10 @@ http://maven.apache.org - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-security-thymeleaf/pom.xml b/spring-security-thymeleaf/pom.xml index aa36e5f59a..28d6126b55 100644 --- a/spring-security-thymeleaf/pom.xml +++ b/spring-security-thymeleaf/pom.xml @@ -10,10 +10,10 @@ Spring Security with Thymeleaf tutorial - parent-boot-5 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-2 diff --git a/spring-security-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java b/spring-security-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java index 687c0c2e39..0a4344db4d 100644 --- a/spring-security-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java +++ b/spring-security-thymeleaf/src/main/java/com/baeldung/springsecuritythymeleaf/SecurityConfiguration.java @@ -1,11 +1,13 @@ package com.baeldung.springsecuritythymeleaf; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @@ -33,11 +35,16 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") - .password("password") + .password(passwordEncoder().encode("password")) .roles("USER") .and() .withUser("admin") - .password("admin") + .password(passwordEncoder().encode("admin")) .roles("ADMIN"); } + + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/spring-security-x509/pom.xml b/spring-security-x509/pom.xml index 89fed39920..d6a4b5693b 100644 --- a/spring-security-x509/pom.xml +++ b/spring-security-x509/pom.xml @@ -9,10 +9,10 @@ pom - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-session/pom.xml b/spring-session/pom.xml index c1c872ca74..4c256663b0 100644 --- a/spring-session/pom.xml +++ b/spring-session/pom.xml @@ -7,10 +7,10 @@ jar - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-sleuth/pom.xml b/spring-sleuth/pom.xml index 2fee474dbe..418edeaec7 100644 --- a/spring-sleuth/pom.xml +++ b/spring-sleuth/pom.xml @@ -8,10 +8,10 @@ jar - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-social-login/pom.xml b/spring-social-login/pom.xml index d2e9497bcf..d08600a8e4 100644 --- a/spring-social-login/pom.xml +++ b/spring-social-login/pom.xml @@ -6,10 +6,10 @@ war - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/spring-thymeleaf/pom.xml b/spring-thymeleaf/pom.xml index d13356b3d7..6e0b7f6545 100644 --- a/spring-thymeleaf/pom.xml +++ b/spring-thymeleaf/pom.xml @@ -173,4 +173,4 @@ 2.2 - \ No newline at end of file + diff --git a/spring-webflux-amqp/.gitignore b/spring-webflux-amqp/.gitignore new file mode 100755 index 0000000000..82eca336e3 --- /dev/null +++ b/spring-webflux-amqp/.gitignore @@ -0,0 +1,25 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/spring-webflux-amqp/pom.xml b/spring-webflux-amqp/pom.xml new file mode 100755 index 0000000000..75fafd7b10 --- /dev/null +++ b/spring-webflux-amqp/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + org.baeldung.spring + spring-webflux-amqp + 1.0.0-SNAPSHOT + jar + + spring-webflux-amqp + Spring WebFlux AMQP Sample + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + + io.projectreactor + reactor-test + test + + + + org.springframework.boot + spring-boot-starter-integration + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/libs-snapshot + + true + + + + + + + spring-releases + Spring Releases + https://repo.spring.io/libs-release + + + + + diff --git a/spring-webflux-amqp/src/docker/docker-compose.yml b/spring-webflux-amqp/src/docker/docker-compose.yml new file mode 100755 index 0000000000..03292aeb63 --- /dev/null +++ b/spring-webflux-amqp/src/docker/docker-compose.yml @@ -0,0 +1,23 @@ +## +## Create a simple RabbitMQ environment with multiple clients +## +version: "3" + +services: + +## +## RabitMQ server +## + rabbitmq: + image: rabbitmq:3 + hostname: rabbit + environment: + RABBITMQ_ERLANG_COOKIE: test + ports: + - "5672:5672" + volumes: + - rabbitmq-data:/var/lib/rabbitmq + +volumes: + rabbitmq-data: + diff --git a/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/DestinationsConfig.java b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/DestinationsConfig.java new file mode 100755 index 0000000000..410b87c764 --- /dev/null +++ b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/DestinationsConfig.java @@ -0,0 +1,59 @@ +package org.baeldung.spring.amqp; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties("destinations") +public class DestinationsConfig { + + + private Map queues = new HashMap<>(); + + private Map topics = new HashMap<>(); + + + + public Map getQueues() { + return queues; + } + + public void setQueues(Map queues) { + this.queues = queues; + } + + public Map getTopics() { + return topics; + } + + public void setTopics(Map topics) { + this.topics = topics; + } + + // DestinationInfo stores the Exchange name and routing key used + // by our producers when posting messages + static class DestinationInfo { + + private String exchange; + private String routingKey; + + + public String getExchange() { + return exchange; + } + public void setExchange(String exchange) { + this.exchange = exchange; + } + public String getRoutingKey() { + return routingKey; + } + public void setRoutingKey(String routingKey) { + this.routingKey = routingKey; + } + + + + } + +} diff --git a/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java new file mode 100755 index 0000000000..eb3b858ddc --- /dev/null +++ b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java @@ -0,0 +1,270 @@ +package org.baeldung.spring.amqp; + +import java.util.stream.Stream; + +import org.baeldung.spring.amqp.DestinationsConfig.DestinationInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.AmqpException; +import org.springframework.amqp.core.AmqpAdmin; +import org.springframework.amqp.core.AmqpTemplate; +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.Exchange; +import org.springframework.amqp.core.ExchangeBuilder; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; + +@SpringBootApplication +@EnableConfigurationProperties(DestinationsConfig.class) +@RestController +public class SpringWebfluxAmqpApplication { + + private static Logger log = LoggerFactory.getLogger(SpringWebfluxAmqpApplication.class); + + @Autowired + private AmqpTemplate amqpTemplate; + + @Autowired + private AmqpAdmin amqpAdmin; + + @Autowired + private DestinationsConfig destinationsConfig; + + + public static void main(String[] args) { + SpringApplication.run(SpringWebfluxAmqpApplication.class, args); + } + + @Bean + public CommandLineRunner setupQueueDestinations(AmqpAdmin amqpAdmin,DestinationsConfig destinationsConfig) { + + return (args) -> { + + log.info("[I48] Creating Destinations..."); + + destinationsConfig.getQueues() + .forEach((key, destination) -> { + + log.info("[I54] Creating directExchange: key={}, name={}, routingKey={}", key, destination.getExchange(), destination.getRoutingKey()); + + Exchange ex = ExchangeBuilder + .directExchange(destination.getExchange()) + .durable(true) + .build(); + + amqpAdmin.declareExchange(ex); + + Queue q = QueueBuilder + .durable(destination.getRoutingKey()) + .build(); + + amqpAdmin.declareQueue(q); + + Binding b = BindingBuilder.bind(q) + .to(ex) + .with(destination.getRoutingKey()) + .noargs(); + amqpAdmin.declareBinding(b); + + log.info("[I70] Binding successfully created."); + + }); + + }; + + } + + @Bean + public CommandLineRunner setupTopicDestinations(AmqpAdmin amqpAdmin, DestinationsConfig destinationsConfig) { + + return (args) -> { + + // For topic each consumer will have its own Queue, so no binding + destinationsConfig.getTopics() + .forEach((key, destination) -> { + + log.info("[I98] Creating TopicExchange: name={}, exchange={}", key, destination.getExchange()); + + Exchange ex = ExchangeBuilder.topicExchange(destination.getExchange()) + .durable(true) + .build(); + + amqpAdmin.declareExchange(ex); + + log.info("[I107] Topic Exchange successfully created."); + + }); + }; + } + + @PostMapping(value = "/queue/{name}") + public Mono> sendMessageToQueue(@PathVariable String name, @RequestBody String payload) { + + // Lookup exchange details + final DestinationInfo d = destinationsConfig.getQueues() + .get(name); + if (d == null) { + // Destination not found. + return Mono.just(ResponseEntity.notFound().build()); + } + + return Mono.fromCallable(() -> { + + log.info("[I51] sendMessageToQueue: queue={}, routingKey={}", d.getExchange(), d.getRoutingKey()); + amqpTemplate.convertAndSend(d.getExchange(), d.getRoutingKey(), payload); + + return ResponseEntity.accepted().build(); + + }); + + } + + + /** + * Receive messages for the given queue + * @param name + * @return + */ + @GetMapping(value = "/queue/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux receiveMessagesFromQueue(@PathVariable String name) { + + final DestinationInfo d = destinationsConfig.getQueues().get(name); + + if (d == null) { + return Flux.just(ResponseEntity.notFound().build()); + } + + Stream s = Stream.generate(() -> { + String queueName = d.getRoutingKey(); + + log.info("[I137] Polling {}", queueName); + + Object payload = amqpTemplate.receiveAndConvert(queueName,5000); + if ( payload == null ) { + payload = "No news is good news..."; + } + + return payload.toString(); + }); + + + return Flux + .fromStream(s) + .subscribeOn(Schedulers.elastic()); + + } + + /** + * send message to a given topic + * @param name + * @param payload + * @return + */ + @PostMapping(value = "/topic/{name}") + public Mono> sendMessageToTopic(@PathVariable String name, @RequestBody String payload) { + + // Lookup exchange details + final DestinationInfo d = destinationsConfig.getTopics().get(name); + if (d == null) { + // Destination not found. + return Mono.just(ResponseEntity.notFound().build()); + } + + return Mono.fromCallable(() -> { + + log.info("[I51] sendMessageToTopic: topic={}, routingKey={}", d.getExchange(), d.getRoutingKey()); + amqpTemplate.convertAndSend(d.getExchange(), d.getRoutingKey(), payload); + + return ResponseEntity.accepted().build(); + + }); + } + + + @GetMapping(value = "/topic/{name}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux receiveMessagesFromTopic(@PathVariable String name) { + + DestinationInfo d = destinationsConfig.getTopics().get(name); + + if (d == null) { + return Flux.just(ResponseEntity.notFound().build()); + } + + final Queue topicQueue = createTopicQueue(d); + + Stream s = Stream.generate(() -> { + String queueName = topicQueue.getName(); + + log.info("[I137] Polling {}", queueName); + + try { + Object payload = amqpTemplate.receiveAndConvert(queueName,5000); + if ( payload == null ) { + payload = "No news is good news..."; + } + + return payload.toString(); + } + catch(AmqpException ex) { + log.warn("[W247] Received an AMQP Exception: {}", ex.getMessage()); + return null; + } + }); + + + return Flux.fromStream(s) + .doOnCancel(() -> { + log.info("[I250] doOnCancel()"); + amqpAdmin.deleteQueue(topicQueue.getName()); + }) + .subscribeOn(Schedulers.elastic()); + + + } + + + private Queue createTopicQueue(DestinationInfo destination) { + + Exchange ex = ExchangeBuilder.topicExchange(destination.getExchange()) + .durable(true) + .build(); + + amqpAdmin.declareExchange(ex); + + // Create a durable queue + Queue q = QueueBuilder + .durable() + .build(); + + amqpAdmin.declareQueue(q); + + Binding b = BindingBuilder.bind(q) + .to(ex) + .with(destination.getRoutingKey()) + .noargs(); + + amqpAdmin.declareBinding(b); + + return q; + } + + +} diff --git a/spring-webflux-amqp/src/main/resources/application.yml b/spring-webflux-amqp/src/main/resources/application.yml new file mode 100755 index 0000000000..3f527ce4c5 --- /dev/null +++ b/spring-webflux-amqp/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + rabbitmq: + host: 192.168.99.100 + port: 5672 + username: guest + password: guest + +destinations: + queues: + NYSE: + exchange: nyse + routing-key: NYSE + IBOV: + exchange: ibov + routing-key: IBOV + + + topics: + weather: + exchange: alerts + routing-key: WEATHER + + + + + + diff --git a/spring-webflux-amqp/src/test/java/org/baeldung/spring/amqp/SpringWebfluxAmqpLiveTest.java b/spring-webflux-amqp/src/test/java/org/baeldung/spring/amqp/SpringWebfluxAmqpLiveTest.java new file mode 100755 index 0000000000..bda490c189 --- /dev/null +++ b/spring-webflux-amqp/src/test/java/org/baeldung/spring/amqp/SpringWebfluxAmqpLiveTest.java @@ -0,0 +1,26 @@ +package org.baeldung.spring.amqp; + +import org.junit.Test; +import org.springframework.test.web.reactive.server.WebTestClient; + + +public class SpringWebfluxAmqpLiveTest { + + @Test + public void whenSendingAMessageToQueue_thenAcceptedReturnCode() { + + WebTestClient client = WebTestClient.bindToServer() + .baseUrl("http://localhost:8080") + .build(); + + client.post() + .uri("/queue/NYSE") + .syncBody("Test Message") + .exchange() + .expectStatus().isAccepted(); + + } + + + +} diff --git a/spring-zuul/pom.xml b/spring-zuul/pom.xml index b1036c9a8a..37bdb09367 100644 --- a/spring-zuul/pom.xml +++ b/spring-zuul/pom.xml @@ -8,10 +8,10 @@ pom - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/stripe/pom.xml b/stripe/pom.xml index b6dae6e680..ca165934a0 100644 --- a/stripe/pom.xml +++ b/stripe/pom.xml @@ -10,10 +10,10 @@ Demo project for Stripe API - parent-boot-5 + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-1 diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md index 6ab00e58d5..2292c3272a 100644 --- a/testing-modules/junit-5/README.md +++ b/testing-modules/junit-5/README.md @@ -12,5 +12,4 @@ - [JUnit Assert an Exception is Thrown](http://www.baeldung.com/junit-assert-exception) - [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall) - [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration) - - +- [JUnit5 Programmatic Extension Registration with @RegisterExtension](http://www.baeldung.com/junit-5-registerextension-annotation) diff --git a/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java index 4a98bbcb87..1b6431f0c2 100644 --- a/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java +++ b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java @@ -7,6 +7,8 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.powermock.api.mockito.PowerMockito.*; @RunWith(PowerMockRunner.class) @@ -23,7 +25,7 @@ public class PowerMockitoIntegrationTest { when(collaborator.helloMethod()).thenReturn("Hello Baeldung!"); String welcome = collaborator.helloMethod(); - Mockito.verify(collaborator).helloMethod(); + verify(collaborator).helloMethod(); assertEquals("Hello Baeldung!", welcome); } @@ -42,7 +44,7 @@ public class PowerMockitoIntegrationTest { assertEquals("Hello Baeldung!", firstWelcome); assertEquals("Hello Baeldung!", secondWelcome); - verifyStatic(Mockito.times(2)); + verifyStatic(times(2)); CollaboratorWithStaticMethods.firstMethod(Mockito.anyString()); verifyStatic(Mockito.never()); @@ -67,7 +69,7 @@ public class PowerMockitoIntegrationTest { when(mock.finalMethod()).thenReturn("I am a final mock method."); returnValue = mock.finalMethod(); - Mockito.verify(mock).finalMethod(); + verify(mock,times(3)).finalMethod(); assertEquals("I am a final mock method.", returnValue); when(mock, "privateMethod").thenReturn("I am a private mock method."); diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java index f846907fd7..6ec3b34db5 100644 --- a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java @@ -24,7 +24,7 @@ public class MockitoMockIntegrationTest { } @Rule - private ExpectedException thrown = ExpectedException.none(); + public ExpectedException thrown = ExpectedException.none(); @Test public void whenUsingSimpleMock_thenCorrect() { diff --git a/testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java index aa0c6696a4..834d266cc6 100644 --- a/testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java +++ b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java @@ -1,19 +1,5 @@ package com.baeldung.rest.wiremock.introduction; -import com.github.tomakehurst.wiremock.junit.WireMockRule; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.junit.Rule; -import org.junit.Test; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Scanner; - import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.containing; import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; @@ -29,16 +15,46 @@ import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static org.junit.Assert.assertEquals; +import java.io.IOException; +import java.io.InputStream; +import java.net.ServerSocket; +import java.util.Scanner; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.junit.Rule; +import org.junit.Test; +import com.github.tomakehurst.wiremock.junit.WireMockRule; + public class JUnitManagedIntegrationTest { private static final String BAELDUNG_WIREMOCK_PATH = "/baeldung/wiremock"; private static final String APPLICATION_JSON = "application/json"; - + static int port; + + static { + + try { + // Get a free port + ServerSocket s = new ServerSocket(0); + port = s.getLocalPort(); + s.close(); + + } catch (IOException e) { + // No OPS + } + } + @Rule - public WireMockRule wireMockRule = new WireMockRule(); + public WireMockRule wireMockRule = new WireMockRule(port); @Test public void givenJUnitManagedServer_whenMatchingURL_thenCorrect() throws IOException { + stubFor(get(urlPathMatching("/baeldung/.*")) .willReturn(aResponse() .withStatus(200) @@ -46,7 +62,7 @@ public class JUnitManagedIntegrationTest { .withBody("\"testing-library\": \"WireMock\""))); CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock"); + HttpGet request = new HttpGet(String.format("http://localhost:%s/baeldung/wiremock", port)); HttpResponse httpResponse = httpClient.execute(request); String stringResponse = convertHttpResponseToString(httpResponse); @@ -66,7 +82,7 @@ public class JUnitManagedIntegrationTest { .withBody("!!! Service Unavailable !!!"))); CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock"); + HttpGet request = new HttpGet(String.format("http://localhost:%s/baeldung/wiremock", port)); request.addHeader("Accept", "text/html"); HttpResponse httpResponse = httpClient.execute(request); String stringResponse = convertHttpResponseToString(httpResponse); @@ -91,7 +107,7 @@ public class JUnitManagedIntegrationTest { StringEntity entity = new StringEntity(jsonString); CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpPost request = new HttpPost("http://localhost:8080/baeldung/wiremock"); + HttpPost request = new HttpPost(String.format("http://localhost:%s/baeldung/wiremock", port)); request.addHeader("Content-Type", APPLICATION_JSON); request.setEntity(entity); HttpResponse response = httpClient.execute(request); @@ -137,7 +153,7 @@ public class JUnitManagedIntegrationTest { private HttpResponse generateClientAndReceiveResponseForPriorityTests() throws IOException { CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpGet request = new HttpGet("http://localhost:8080/baeldung/wiremock"); + HttpGet request = new HttpGet(String.format("http://localhost:%s/baeldung/wiremock", port)); request.addHeader("Accept", "text/xml"); return httpClient.execute(request); } diff --git a/xmlunit-2/pom.xml b/xmlunit-2/pom.xml index 171f3de03c..0a32b90af5 100644 --- a/xmlunit-2/pom.xml +++ b/xmlunit-2/pom.xml @@ -4,7 +4,6 @@ com.baeldung xmlunit-2 1.0 - XMLUnit-2 com.baeldung